aboutsummaryrefslogtreecommitdiff
path: root/src/utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.h')
-rw-r--r--src/utils.h116
1 files changed, 84 insertions, 32 deletions
diff --git a/src/utils.h b/src/utils.h
index bd5589cc..f6e50e51 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -20,6 +20,7 @@
#include "src/globals.h"
#include "src/list.h"
#include "src/vector.h"
+#include "src/zone/zone.h"
namespace v8 {
namespace internal {
@@ -136,15 +137,20 @@ inline int MostSignificantBit(uint32_t x) {
return nibble + msb4[x];
}
-
-// The C++ standard leaves the semantics of '>>' undefined for
-// negative signed operands. Most implementations do the right thing,
-// though.
-inline int ArithmeticShiftRight(int x, int s) {
- return x >> s;
+template <typename T>
+static T ArithmeticShiftRight(T x, int shift) {
+ DCHECK_LE(0, shift);
+ if (x < 0) {
+ // Right shift of signed values is implementation defined. Simulate a
+ // true arithmetic right shift by adding leading sign bits.
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ UnsignedT mask = ~(static_cast<UnsignedT>(~0) >> shift);
+ return (static_cast<UnsignedT>(x) >> shift) | mask;
+ } else {
+ return x >> shift;
+ }
}
-
template <typename T>
int Compare(const T& a, const T& b) {
if (a == b)
@@ -186,6 +192,11 @@ inline bool IsAddressAligned(Address addr,
return IsAligned(offs, alignment);
}
+template <typename T, typename U>
+inline T RoundUpToMultipleOfPowOf2(T value, U multiple) {
+ DCHECK(multiple && ((multiple & (multiple - 1)) == 0));
+ return (value + multiple - 1) & ~(multiple - 1);
+}
// Returns the maximum of the two parameters.
template <typename T>
@@ -502,13 +513,22 @@ V8_EXPORT_PRIVATE V8_INLINE void MemMove(void* dest, const void* src,
size_t size) {
memmove(dest, src, size);
}
-const int kMinComplexMemCopy = 16 * kPointerSize;
+const int kMinComplexMemCopy = 8;
#endif // V8_TARGET_ARCH_IA32
// ----------------------------------------------------------------------------
// Miscellaneous
+// Memory offset for lower and higher bits in a 64 bit integer.
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+static const int kInt64LowerHalfMemoryOffset = 0;
+static const int kInt64UpperHalfMemoryOffset = 4;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+static const int kInt64LowerHalfMemoryOffset = 4;
+static const int kInt64UpperHalfMemoryOffset = 0;
+#endif // V8_TARGET_LITTLE_ENDIAN
+
// A static resource holds a static instance that can be reserved in
// a local scope using an instance of Access. Attempts to re-reserve
// the instance will cause an error.
@@ -879,24 +899,21 @@ inline bool operator>(TypeFeedbackId lhs, TypeFeedbackId rhs) {
return lhs.ToInt() > rhs.ToInt();
}
-
-class FeedbackVectorSlot {
+class FeedbackSlot {
public:
- FeedbackVectorSlot() : id_(kInvalidSlot) {}
- explicit FeedbackVectorSlot(int id) : id_(id) {}
+ FeedbackSlot() : id_(kInvalidSlot) {}
+ explicit FeedbackSlot(int id) : id_(id) {}
int ToInt() const { return id_; }
- static FeedbackVectorSlot Invalid() { return FeedbackVectorSlot(); }
+ static FeedbackSlot Invalid() { return FeedbackSlot(); }
bool IsInvalid() const { return id_ == kInvalidSlot; }
- bool operator==(FeedbackVectorSlot that) const {
- return this->id_ == that.id_;
- }
- bool operator!=(FeedbackVectorSlot that) const { return !(*this == that); }
+ bool operator==(FeedbackSlot that) const { return this->id_ == that.id_; }
+ bool operator!=(FeedbackSlot that) const { return !(*this == that); }
- friend size_t hash_value(FeedbackVectorSlot slot) { return slot.ToInt(); }
- friend std::ostream& operator<<(std::ostream& os, FeedbackVectorSlot);
+ friend size_t hash_value(FeedbackSlot slot) { return slot.ToInt(); }
+ friend std::ostream& operator<<(std::ostream& os, FeedbackSlot);
private:
static const int kInvalidSlot = -1;
@@ -918,6 +935,17 @@ class BailoutId {
static BailoutId FirstUsable() { return BailoutId(kFirstUsableId); }
static BailoutId StubEntry() { return BailoutId(kStubEntryId); }
+ // Special bailout id support for deopting into the {JSConstructStub} stub.
+ // The following hard-coded deoptimization points are supported by the stub:
+ // - {ConstructStubCreate} maps to {construct_stub_create_deopt_pc_offset}.
+ // - {ConstructStubInvoke} maps to {construct_stub_invoke_deopt_pc_offset}.
+ static BailoutId ConstructStubCreate() { return BailoutId(1); }
+ static BailoutId ConstructStubInvoke() { return BailoutId(2); }
+ bool IsValidForConstructStub() const {
+ return id_ == ConstructStubCreate().ToInt() ||
+ id_ == ConstructStubInvoke().ToInt();
+ }
+
bool IsNone() const { return id_ == kNoneId; }
bool operator==(const BailoutId& other) const { return id_ == other.id_; }
bool operator!=(const BailoutId& other) const { return id_ != other.id_; }
@@ -946,19 +974,6 @@ class BailoutId {
int id_;
};
-class TokenDispenserForFinally {
- public:
- int GetBreakContinueToken() { return next_token_++; }
- static const int kFallThroughToken = 0;
- static const int kThrowToken = 1;
- static const int kReturnToken = 2;
-
- static const int kFirstBreakContinueToken = 3;
- static const int kInvalidToken = -1;
-
- private:
- int next_token_ = kFirstBreakContinueToken;
-};
// ----------------------------------------------------------------------------
// I/O support.
@@ -1640,9 +1655,31 @@ class ThreadedList final {
friend class ThreadedList;
};
+ class ConstIterator final {
+ public:
+ ConstIterator& operator++() {
+ entry_ = (*entry_)->next();
+ return *this;
+ }
+ bool operator!=(const ConstIterator& other) {
+ return entry_ != other.entry_;
+ }
+ const T* operator*() const { return *entry_; }
+
+ private:
+ explicit ConstIterator(T* const* entry) : entry_(entry) {}
+
+ T* const* entry_;
+
+ friend class ThreadedList;
+ };
+
Iterator begin() { return Iterator(&head_); }
Iterator end() { return Iterator(tail_); }
+ ConstIterator begin() const { return ConstIterator(&head_); }
+ ConstIterator end() const { return ConstIterator(tail_); }
+
void Rewind(Iterator reset_point) {
tail_ = reset_point.entry_;
*tail_ = nullptr;
@@ -1677,6 +1714,21 @@ class ThreadedList final {
DISALLOW_COPY_AND_ASSIGN(ThreadedList);
};
+// Can be used to create a threaded list of |T|.
+template <typename T>
+class ThreadedListZoneEntry final : public ZoneObject {
+ public:
+ explicit ThreadedListZoneEntry(T value) : value_(value), next_(nullptr) {}
+
+ T value() { return value_; }
+ ThreadedListZoneEntry<T>** next() { return &next_; }
+
+ private:
+ T value_;
+ ThreadedListZoneEntry<T>* next_;
+ DISALLOW_COPY_AND_ASSIGN(ThreadedListZoneEntry);
+};
+
} // namespace internal
} // namespace v8