Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/utils.h b/src/utils.h
index 525c6f8..1ea2d56 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -26,6 +26,19 @@
// ----------------------------------------------------------------------------
// General helper functions
+// Returns the value (0 .. 15) of a hexadecimal character c.
+// If c is not a legal hexadecimal character, returns a value < 0.
+inline int HexValue(uc32 c) {
+ c -= '0';
+ if (static_cast<unsigned>(c) <= 9) return c;
+ c = (c | 0x20) - ('a' - '0'); // detect 0x11..0x16 and 0x31..0x36.
+ if (static_cast<unsigned>(c) <= 5) return c + 10;
+ return -1;
+}
+
+
+inline int BoolToInt(bool b) { return b ? 1 : 0; }
+
// Same as strcmp, but can handle NULL arguments.
inline bool CStringEquals(const char* s1, const char* s2) {
@@ -38,7 +51,7 @@
DCHECK(base::bits::IsPowerOfTwo32(x));
int bits = 0;
#ifdef DEBUG
- int original_x = x;
+ uint32_t original_x = x;
#endif
if (x >= 0x10000) {
bits += 16;
@@ -59,7 +72,42 @@
case 2: bits++; // Fall through.
case 1: break;
}
- DCHECK_EQ(1 << bits, original_x);
+ DCHECK_EQ(static_cast<uint32_t>(1) << bits, original_x);
+ return bits;
+}
+
+
+// X must be a power of 2. Returns the number of trailing zeros.
+inline int WhichPowerOf2_64(uint64_t x) {
+ DCHECK(base::bits::IsPowerOfTwo64(x));
+ int bits = 0;
+#ifdef DEBUG
+ uint64_t original_x = x;
+#endif
+ if (x >= 0x100000000L) {
+ bits += 32;
+ x >>= 32;
+ }
+ if (x >= 0x10000) {
+ bits += 16;
+ x >>= 16;
+ }
+ if (x >= 0x100) {
+ bits += 8;
+ x >>= 8;
+ }
+ if (x >= 0x10) {
+ bits += 4;
+ x >>= 4;
+ }
+ switch (x) {
+ default: UNREACHABLE();
+ case 8: bits++; // Fall through.
+ case 4: bits++; // Fall through.
+ case 2: bits++; // Fall through.
+ case 1: break;
+ }
+ DCHECK_EQ(static_cast<uint64_t>(1) << bits, original_x);
return bits;
}
@@ -205,7 +253,7 @@
static const U kNext = kShift + kSize;
// Value for the field with all bits set.
- static const T kMax = static_cast<T>((1U << size) - 1);
+ static const T kMax = static_cast<T>((kOne << size) - 1);
// Tells whether the provided value fits into the bit field.
static bool is_valid(T value) {
@@ -302,7 +350,7 @@
hash = hash ^ (hash >> 4);
hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11);
hash = hash ^ (hash >> 16);
- return hash;
+ return hash & 0x3fffffff;
}
@@ -328,9 +376,8 @@
// ----------------------------------------------------------------------------
// Generated memcpy/memmove
-// Initializes the codegen support that depends on CPU features. This is
-// called after CPU initialization.
-void init_memcopy_functions();
+// Initializes the codegen support that depends on CPU features.
+void init_memcopy_functions(Isolate* isolate);
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
// Limit below which the extra overhead of the MemCopy function is likely
@@ -602,7 +649,14 @@
}
// Resets the collector to be empty.
- virtual void Reset();
+ virtual void Reset() {
+ for (int i = chunks_.length() - 1; i >= 0; i--) {
+ chunks_.at(i).Dispose();
+ }
+ chunks_.Rewind(0);
+ index_ = 0;
+ size_ = 0;
+ }
// Total number of elements added to collector so far.
inline int size() { return size_; }
@@ -730,9 +784,8 @@
// Compare 8bit/16bit chars to 8bit/16bit chars.
template <typename lchar, typename rchar>
-inline int CompareCharsUnsigned(const lchar* lhs,
- const rchar* rhs,
- int chars) {
+inline int CompareCharsUnsigned(const lchar* lhs, const rchar* rhs,
+ size_t chars) {
const lchar* limit = lhs + chars;
if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) {
// memcmp compares byte-by-byte, yielding wrong results for two-byte
@@ -748,8 +801,8 @@
return 0;
}
-template<typename lchar, typename rchar>
-inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
+template <typename lchar, typename rchar>
+inline int CompareChars(const lchar* lhs, const rchar* rhs, size_t chars) {
DCHECK(sizeof(lchar) <= 2);
DCHECK(sizeof(rchar) <= 2);
if (sizeof(lchar) == 1) {
@@ -998,22 +1051,31 @@
int id_;
};
+inline bool operator<(TypeFeedbackId lhs, TypeFeedbackId rhs) {
+ return lhs.ToInt() < rhs.ToInt();
+}
+inline bool operator>(TypeFeedbackId lhs, TypeFeedbackId rhs) {
+ return lhs.ToInt() > rhs.ToInt();
+}
-template <int dummy_parameter>
-class VectorSlot {
+
+class FeedbackVectorSlot {
public:
- explicit VectorSlot(int id) : id_(id) {}
+ FeedbackVectorSlot() : id_(kInvalidSlot) {}
+ explicit FeedbackVectorSlot(int id) : id_(id) {}
+
int ToInt() const { return id_; }
- static VectorSlot Invalid() { return VectorSlot(kInvalidSlot); }
+ static FeedbackVectorSlot Invalid() { return FeedbackVectorSlot(); }
bool IsInvalid() const { return id_ == kInvalidSlot; }
- VectorSlot next() const {
- DCHECK(id_ != kInvalidSlot);
- return VectorSlot(id_ + 1);
+ bool operator==(FeedbackVectorSlot that) const {
+ return this->id_ == that.id_;
}
+ bool operator!=(FeedbackVectorSlot that) const { return !(*this == that); }
- bool operator==(const VectorSlot& other) const { return id_ == other.id_; }
+ friend size_t hash_value(FeedbackVectorSlot slot) { return slot.ToInt(); }
+ friend std::ostream& operator<<(std::ostream& os, FeedbackVectorSlot);
private:
static const int kInvalidSlot = -1;
@@ -1022,16 +1084,14 @@
};
-typedef VectorSlot<0> FeedbackVectorSlot;
-typedef VectorSlot<1> FeedbackVectorICSlot;
-
-
class BailoutId {
public:
explicit BailoutId(int id) : id_(id) { }
int ToInt() const { return id_; }
static BailoutId None() { return BailoutId(kNoneId); }
+ static BailoutId ScriptContext() { return BailoutId(kScriptContextId); }
+ static BailoutId FunctionContext() { return BailoutId(kFunctionContextId); }
static BailoutId FunctionEntry() { return BailoutId(kFunctionEntryId); }
static BailoutId Declarations() { return BailoutId(kDeclarationsId); }
static BailoutId FirstUsable() { return BailoutId(kFirstUsableId); }
@@ -1047,38 +1107,25 @@
static const int kNoneId = -1;
// Using 0 could disguise errors.
- static const int kFunctionEntryId = 2;
+ static const int kScriptContextId = 1;
+ static const int kFunctionContextId = 2;
+ static const int kFunctionEntryId = 3;
// This AST id identifies the point after the declarations have been visited.
// We need it to capture the environment effects of declarations that emit
// code (function declarations).
- static const int kDeclarationsId = 3;
+ static const int kDeclarationsId = 4;
// Every FunctionState starts with this id.
- static const int kFirstUsableId = 4;
+ static const int kFirstUsableId = 5;
// Every compiled stub starts with this id.
- static const int kStubEntryId = 5;
+ static const int kStubEntryId = 6;
int id_;
};
-template <class C>
-class ContainerPointerWrapper {
- public:
- typedef typename C::iterator iterator;
- typedef typename C::reverse_iterator reverse_iterator;
- explicit ContainerPointerWrapper(C* container) : container_(container) {}
- iterator begin() { return container_->begin(); }
- iterator end() { return container_->end(); }
- reverse_iterator rbegin() { return container_->rbegin(); }
- reverse_iterator rend() { return container_->rend(); }
- private:
- C* container_;
-};
-
-
// ----------------------------------------------------------------------------
// I/O support.
@@ -1111,6 +1158,9 @@
// Prepends the current process ID to the output.
void PRINTF_CHECKING PrintPID(const char* format, ...);
+// Prepends the current process ID and given isolate pointer to the output.
+void PrintIsolate(void* isolate, const char* format, ...);
+
// Safe formatting print. Ensures that str is always null-terminated.
// Returns the number of chars written, or -1 if output was truncated.
int FPRINTF_CHECKING SNPrintF(Vector<char> str, const char* format, ...);
@@ -1170,17 +1220,6 @@
// ----------------------------------------------------------------------------
-// Data structures
-
-template <typename T>
-inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
- int length) {
- return Vector< Handle<Object> >(
- reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
-}
-
-
-// ----------------------------------------------------------------------------
// Memory
// Copies words from |src| to |dst|. The data spans must not overlap.
@@ -1314,24 +1353,30 @@
template <typename sourcechar, typename sinkchar>
-INLINE(static void CopyCharsUnsigned(sinkchar* dest,
- const sourcechar* src,
- int chars));
+INLINE(static void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src,
+ size_t chars));
#if defined(V8_HOST_ARCH_ARM)
-INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
-INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
-INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
+INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src,
+ size_t chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
+ size_t chars));
#elif defined(V8_HOST_ARCH_MIPS)
-INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
-INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
+INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
+ size_t chars));
+#elif defined(V8_HOST_ARCH_PPC)
+INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src,
+ size_t chars));
#endif
// Copy from 8bit/16bit chars to 8bit/16bit chars.
template <typename sourcechar, typename sinkchar>
-INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
+INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars));
-template<typename sourcechar, typename sinkchar>
-void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
+template <typename sourcechar, typename sinkchar>
+void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars) {
DCHECK(sizeof(sourcechar) <= 2);
DCHECK(sizeof(sinkchar) <= 2);
if (sizeof(sinkchar) == 1) {
@@ -1358,7 +1403,7 @@
}
template <typename sourcechar, typename sinkchar>
-void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
+void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, size_t chars) {
sinkchar* limit = dest + chars;
if ((sizeof(*dest) == sizeof(*src)) &&
(chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest)))) {
@@ -1370,7 +1415,7 @@
#if defined(V8_HOST_ARCH_ARM)
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
+void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
switch (static_cast<unsigned>(chars)) {
case 0:
break;
@@ -1426,8 +1471,8 @@
}
-void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
- if (chars >= kMinComplexConvertMemCopy) {
+void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, size_t chars) {
+ if (chars >= static_cast<size_t>(kMinComplexConvertMemCopy)) {
MemCopyUint16Uint8(dest, src, chars);
} else {
MemCopyUint16Uint8Wrapper(dest, src, chars);
@@ -1435,7 +1480,7 @@
}
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
+void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
switch (static_cast<unsigned>(chars)) {
case 0:
break;
@@ -1468,7 +1513,7 @@
#elif defined(V8_HOST_ARCH_MIPS)
-void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
+void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
if (chars < kMinComplexMemCopy) {
memcpy(dest, src, chars);
} else {
@@ -1476,13 +1521,143 @@
}
}
-void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
+void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
if (chars < kMinComplexMemCopy) {
memcpy(dest, src, chars * sizeof(*dest));
} else {
MemCopy(dest, src, chars * sizeof(*dest));
}
}
+#elif defined(V8_HOST_ARCH_PPC)
+#define CASE(n) \
+ case n: \
+ memcpy(dest, src, n); \
+ break
+void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) {
+ switch (static_cast<unsigned>(chars)) {
+ case 0:
+ break;
+ case 1:
+ *dest = *src;
+ break;
+ CASE(2);
+ CASE(3);
+ CASE(4);
+ CASE(5);
+ CASE(6);
+ CASE(7);
+ CASE(8);
+ CASE(9);
+ CASE(10);
+ CASE(11);
+ CASE(12);
+ CASE(13);
+ CASE(14);
+ CASE(15);
+ CASE(16);
+ CASE(17);
+ CASE(18);
+ CASE(19);
+ CASE(20);
+ CASE(21);
+ CASE(22);
+ CASE(23);
+ CASE(24);
+ CASE(25);
+ CASE(26);
+ CASE(27);
+ CASE(28);
+ CASE(29);
+ CASE(30);
+ CASE(31);
+ CASE(32);
+ CASE(33);
+ CASE(34);
+ CASE(35);
+ CASE(36);
+ CASE(37);
+ CASE(38);
+ CASE(39);
+ CASE(40);
+ CASE(41);
+ CASE(42);
+ CASE(43);
+ CASE(44);
+ CASE(45);
+ CASE(46);
+ CASE(47);
+ CASE(48);
+ CASE(49);
+ CASE(50);
+ CASE(51);
+ CASE(52);
+ CASE(53);
+ CASE(54);
+ CASE(55);
+ CASE(56);
+ CASE(57);
+ CASE(58);
+ CASE(59);
+ CASE(60);
+ CASE(61);
+ CASE(62);
+ CASE(63);
+ CASE(64);
+ default:
+ memcpy(dest, src, chars);
+ break;
+ }
+}
+#undef CASE
+
+#define CASE(n) \
+ case n: \
+ memcpy(dest, src, n * 2); \
+ break
+void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) {
+ switch (static_cast<unsigned>(chars)) {
+ case 0:
+ break;
+ case 1:
+ *dest = *src;
+ break;
+ CASE(2);
+ CASE(3);
+ CASE(4);
+ CASE(5);
+ CASE(6);
+ CASE(7);
+ CASE(8);
+ CASE(9);
+ CASE(10);
+ CASE(11);
+ CASE(12);
+ CASE(13);
+ CASE(14);
+ CASE(15);
+ CASE(16);
+ CASE(17);
+ CASE(18);
+ CASE(19);
+ CASE(20);
+ CASE(21);
+ CASE(22);
+ CASE(23);
+ CASE(24);
+ CASE(25);
+ CASE(26);
+ CASE(27);
+ CASE(28);
+ CASE(29);
+ CASE(30);
+ CASE(31);
+ CASE(32);
+ default:
+ memcpy(dest, src, chars * 2);
+ break;
+ }
+}
+#undef CASE
#endif
@@ -1522,7 +1697,7 @@
d = stream->GetNext() - '0';
if (d < 0 || d > 9) return false;
// Check that the new result is below the 32 bit limit.
- if (result > 429496729U - ((d > 5) ? 1 : 0)) return false;
+ if (result > 429496729U - ((d + 3) >> 3)) return false;
result = (result * 10) + d;
}
@@ -1540,6 +1715,77 @@
return limit;
}
+static inline double ReadDoubleValue(const void* p) {
+#ifndef V8_TARGET_ARCH_MIPS
+ return *reinterpret_cast<const double*>(p);
+#else // V8_TARGET_ARCH_MIPS
+ // Prevent compiler from using load-double (mips ldc1) on (possibly)
+ // non-64-bit aligned address.
+ union conversion {
+ double d;
+ uint32_t u[2];
+ } c;
+ const uint32_t* ptr = reinterpret_cast<const uint32_t*>(p);
+ c.u[0] = *ptr;
+ c.u[1] = *(ptr + 1);
+ return c.d;
+#endif // V8_TARGET_ARCH_MIPS
+}
+
+
+static inline void WriteDoubleValue(void* p, double value) {
+#ifndef V8_TARGET_ARCH_MIPS
+ *(reinterpret_cast<double*>(p)) = value;
+#else // V8_TARGET_ARCH_MIPS
+ // Prevent compiler from using load-double (mips sdc1) on (possibly)
+ // non-64-bit aligned address.
+ union conversion {
+ double d;
+ uint32_t u[2];
+ } c;
+ c.d = value;
+ uint32_t* ptr = reinterpret_cast<uint32_t*>(p);
+ *ptr = c.u[0];
+ *(ptr + 1) = c.u[1];
+#endif // V8_TARGET_ARCH_MIPS
+}
+
+
+static inline uint16_t ReadUnalignedUInt16(const void* p) {
+#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
+ return *reinterpret_cast<const uint16_t*>(p);
+#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+ // Prevent compiler from using load-half (mips lh) on (possibly)
+ // non-16-bit aligned address.
+ union conversion {
+ uint16_t h;
+ uint8_t b[2];
+ } c;
+ const uint8_t* ptr = reinterpret_cast<const uint8_t*>(p);
+ c.b[0] = *ptr;
+ c.b[1] = *(ptr + 1);
+ return c.h;
+#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+}
+
+
+static inline void WriteUnalignedUInt16(void* p, uint16_t value) {
+#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
+ *(reinterpret_cast<uint16_t*>(p)) = value;
+#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+ // Prevent compiler from using store-half (mips sh) on (possibly)
+ // non-16-bit aligned address.
+ union conversion {
+ uint16_t h;
+ uint8_t b[2];
+ } c;
+ c.h = value;
+ uint8_t* ptr = reinterpret_cast<uint8_t*>(p);
+ *ptr = c.b[0];
+ *(ptr + 1) = c.b[1];
+#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+}
+
} // namespace internal
} // namespace v8