summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorAli Ijaz Sheikh <ofrobots@google.com>2016-05-04 16:46:17 +0200
committerAli Ijaz Sheikh <ofrobots@google.com>2016-05-11 18:46:47 -0700
commite16e611089f0bf1870a760f7e344e8da6f001428 (patch)
treeb04581928b854007a20b2fc6c3ce0ce357d02806 /deps
parentfe4837afcc17566a44a7744fb77c195e7b3bf2fd (diff)
downloadandroid-node-v8-e16e611089f0bf1870a760f7e344e8da6f001428.tar.gz
android-node-v8-e16e611089f0bf1870a760f7e344e8da6f001428.tar.bz2
android-node-v8-e16e611089f0bf1870a760f7e344e8da6f001428.zip
deps: upgrade to V8 5.0.71.47
Pick up the latest set of patch level updates from the V8 5.0 branch. https://github.com/v8/v8/compare/5.0.71.35...5.0.71.47 PR-URL: https://github.com/nodejs/node/pull/6572 Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: JungMinu - Minwoo Jung <jmwsoft@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/include/v8-version.h2
-rw-r--r--deps/v8/src/arm/code-stubs-arm.cc81
-rw-r--r--deps/v8/src/arm64/code-stubs-arm64.cc94
-rw-r--r--deps/v8/src/compiler/ia32/instruction-selector-ia32.cc3
-rw-r--r--deps/v8/src/compiler/js-generic-lowering.cc118
-rw-r--r--deps/v8/src/compiler/js-generic-lowering.h1
-rw-r--r--deps/v8/src/compiler/x64/instruction-selector-x64.cc7
-rw-r--r--deps/v8/src/debug/debug-evaluate.cc1
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.cc100
-rw-r--r--deps/v8/src/ic/ic.cc30
-rw-r--r--deps/v8/src/ic/ic.h20
-rw-r--r--deps/v8/src/interpreter/interpreter.cc16
-rw-r--r--deps/v8/src/isolate.cc2
-rw-r--r--deps/v8/src/mips/code-stubs-mips.cc85
-rw-r--r--deps/v8/src/mips64/code-stubs-mips64.cc97
-rw-r--r--deps/v8/src/objects-inl.h4
-rw-r--r--deps/v8/src/objects.cc20
-rw-r--r--deps/v8/src/objects.h3
-rw-r--r--deps/v8/src/ppc/code-stubs-ppc.cc82
-rw-r--r--deps/v8/src/runtime/runtime-interpreter.cc103
-rw-r--r--deps/v8/src/runtime/runtime-object.cc22
-rw-r--r--deps/v8/src/runtime/runtime-operators.cc76
-rw-r--r--deps/v8/src/runtime/runtime.h20
-rw-r--r--deps/v8/src/type-feedback-vector.cc33
-rw-r--r--deps/v8/src/type-feedback-vector.h4
-rw-r--r--deps/v8/src/type-info.cc2
-rw-r--r--deps/v8/src/x64/code-stubs-x64.cc95
-rw-r--r--deps/v8/src/x87/code-stubs-x87.cc98
-rw-r--r--deps/v8/src/zone.cc10
-rw-r--r--deps/v8/test/cctest/test-regexp.cc23
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status1
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4788-1.js25
-rw-r--r--deps/v8/test/mjsunit/regress/regress-4788-2.js25
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-594183.js82
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-605581.js28
-rw-r--r--deps/v8/test/mjsunit/regress/regress-v8-4972.js5
-rw-r--r--deps/v8/test/mjsunit/undetectable-compare.js1
-rw-r--r--deps/v8/test/unittests/runtime/runtime-interpreter-unittest.cc99
-rw-r--r--deps/v8/tools/gen-postmortem-metadata.py2
39 files changed, 736 insertions, 784 deletions
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index 130a93c05e..cde8bf192d 100644
--- a/deps/v8/include/v8-version.h
+++ b/deps/v8/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 5
#define V8_MINOR_VERSION 0
#define V8_BUILD_NUMBER 71
-#define V8_PATCH_LEVEL 35
+#define V8_PATCH_LEVEL 47
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc
index 239eddd28e..82fb51d2f1 100644
--- a/deps/v8/src/arm/code-stubs-arm.cc
+++ b/deps/v8/src/arm/code-stubs-arm.cc
@@ -671,11 +671,19 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
__ bind(&slow);
- __ Push(lhs, rhs);
- // Figure out which native to call and setup the arguments.
if (cc == eq) {
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+ __ Push(lhs, rhs);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ LoadRoot(r1, Heap::kTrueValueRootIndex);
+ __ sub(r0, r0, r1);
+ __ Ret();
} else {
+ __ Push(lhs, rhs);
int ncr; // NaN compare result
if (cc == lt || cc == le) {
ncr = GREATER;
@@ -1573,34 +1581,33 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ ldr(subject, MemOperand(sp, kSubjectOffset));
__ JumpIfSmi(subject, &runtime);
__ mov(r3, subject); // Make a copy of the original subject string.
- __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
// subject: subject string
// r3: subject string
- // r0: subject string instance type
// regexp_data: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
- // (1) Sequential string? If yes, go to (5).
- // (2) Anything but sequential or cons? If yes, go to (6).
- // (3) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (4) Is subject external? If yes, go to (7).
- // (5) Sequential string. Load regexp code according to encoding.
+ // (1) Sequential string? If yes, go to (4).
+ // (2) Sequential or cons? If not, go to (5).
+ // (3) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (4) Sequential string. Load regexp code according to encoding.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (6) Not a long external string? If yes, go to (8).
- // (7) External string. Make it, offset-wise, look like a sequential string.
- // Go to (5).
- // (8) Short external string or not a string? If yes, bail out to runtime.
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (5) Long external string? If not, go to (7).
+ // (6) External string. Make it, offset-wise, look like a sequential string.
+ // Go to (4).
+ // (7) Short external string or not a string? If yes, bail out to runtime.
+ // (8) Sliced string. Replace subject with parent. Go to (1).
- Label seq_string /* 5 */, external_string /* 7 */,
- check_underlying /* 4 */, not_seq_nor_cons /* 6 */,
- not_long_external /* 8 */;
+ Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */,
+ not_seq_nor_cons /* 5 */, not_long_external /* 7 */;
- // (1) Sequential string? If yes, go to (5).
+ __ bind(&check_underlying);
+ __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
+ __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
+
+ // (1) Sequential string? If yes, go to (4).
__ and_(r1,
r0,
Operand(kIsNotStringMask |
@@ -1608,15 +1615,15 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
kShortExternalStringMask),
SetCC);
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
- __ b(eq, &seq_string); // Go to (5).
+ __ b(eq, &seq_string); // Go to (4).
- // (2) Anything but sequential or cons? If yes, go to (6).
+ // (2) Sequential or cons? If not, go to (5).
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
__ cmp(r1, Operand(kExternalStringTag));
- __ b(ge, &not_seq_nor_cons); // Go to (6).
+ __ b(ge, &not_seq_nor_cons); // Go to (5).
// (3) Cons string. Check that it's flat.
// Replace subject with first string and reload instance type.
@@ -1624,19 +1631,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ CompareRoot(r0, Heap::kempty_stringRootIndex);
__ b(ne, &runtime);
__ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
+ __ jmp(&check_underlying);
- // (4) Is subject external? If yes, go to (7).
- __ bind(&check_underlying);
- __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
- STATIC_ASSERT(kSeqStringTag == 0);
- __ tst(r0, Operand(kStringRepresentationMask));
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ b(ne, &external_string); // Go to (7).
-
- // (5) Sequential string. Load regexp code according to encoding.
+ // (4) Sequential string. Load regexp code according to encoding.
__ bind(&seq_string);
// subject: sequential subject string (or look-alike, external string)
// r3: original subject string
@@ -1869,12 +1866,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (6) Not a long external string? If yes, go to (8).
+ // (5) Long external string? If not, go to (7).
__ bind(&not_seq_nor_cons);
// Compare flags are still set.
- __ b(gt, &not_long_external); // Go to (8).
+ __ b(gt, &not_long_external); // Go to (7).
- // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (6) External string. Make it, offset-wise, look like a sequential string.
__ bind(&external_string);
__ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
__ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
@@ -1891,15 +1888,15 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ sub(subject,
subject,
Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- __ jmp(&seq_string); // Go to (5).
+ __ jmp(&seq_string); // Go to (4).
- // (8) Short external string or not a string? If yes, bail out to runtime.
+ // (7) Short external string or not a string? If yes, bail out to runtime.
__ bind(&not_long_external);
STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
__ tst(r1, Operand(kIsNotStringMask | kShortExternalStringMask));
__ b(ne, &runtime);
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (8) Sliced string. Replace subject with parent. Go to (4).
// Load offset into r9 and replace subject string with parent.
__ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
__ SmiUntag(r9);
diff --git a/deps/v8/src/arm64/code-stubs-arm64.cc b/deps/v8/src/arm64/code-stubs-arm64.cc
index 57a0ffde92..ad566e68fc 100644
--- a/deps/v8/src/arm64/code-stubs-arm64.cc
+++ b/deps/v8/src/arm64/code-stubs-arm64.cc
@@ -628,11 +628,19 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
__ Bind(&slow);
- __ Push(lhs, rhs);
- // Figure out which native to call and setup the arguments.
if (cond == eq) {
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(lhs, rhs);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ LoadRoot(x1, Heap::kTrueValueRootIndex);
+ __ Sub(x0, x0, x1);
+ __ Ret();
} else {
+ __ Push(lhs, rhs);
int ncr; // NaN compare result
if ((cond == lt) || (cond == le)) {
ncr = GREATER;
@@ -1739,35 +1747,35 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ Peek(subject, kSubjectOffset);
__ JumpIfSmi(subject, &runtime);
- __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset));
-
__ Ldr(jsstring_length, FieldMemOperand(subject, String::kLengthOffset));
// Handle subject string according to its encoding and representation:
- // (1) Sequential string? If yes, go to (5).
- // (2) Anything but sequential or cons? If yes, go to (6).
- // (3) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (4) Is subject external? If yes, go to (7).
- // (5) Sequential string. Load regexp code according to encoding.
+ // (1) Sequential string? If yes, go to (4).
+ // (2) Sequential or cons? If not, go to (5).
+ // (3) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (4) Sequential string. Load regexp code according to encoding.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (6) Not a long external string? If yes, go to (8).
- // (7) External string. Make it, offset-wise, look like a sequential string.
- // Go to (5).
- // (8) Short external string or not a string? If yes, bail out to runtime.
- // (9) Sliced string. Replace subject with parent. Go to (4).
-
- Label check_underlying; // (4)
- Label seq_string; // (5)
- Label not_seq_nor_cons; // (6)
- Label external_string; // (7)
- Label not_long_external; // (8)
-
- // (1) Sequential string? If yes, go to (5).
+ // (5) Long external string? If not, go to (7).
+ // (6) External string. Make it, offset-wise, look like a sequential string.
+ // Go to (4).
+ // (7) Short external string or not a string? If yes, bail out to runtime.
+ // (8) Sliced string. Replace subject with parent. Go to (1).
+
+ Label check_underlying; // (1)
+ Label seq_string; // (4)
+ Label not_seq_nor_cons; // (5)
+ Label external_string; // (6)
+ Label not_long_external; // (7)
+
+ __ Bind(&check_underlying);
+ __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset));
+ __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset));
+
+ // (1) Sequential string? If yes, go to (4).
__ And(string_representation,
string_type,
kIsNotStringMask |
@@ -1784,36 +1792,24 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// is a String
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
STATIC_ASSERT(kShortExternalStringTag != 0);
- __ Cbz(string_representation, &seq_string); // Go to (5).
+ __ Cbz(string_representation, &seq_string); // Go to (4).
- // (2) Anything but sequential or cons? If yes, go to (6).
+ // (2) Sequential or cons? If not, go to (5).
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
__ Cmp(string_representation, kExternalStringTag);
- __ B(ge, &not_seq_nor_cons); // Go to (6).
+ __ B(ge, &not_seq_nor_cons); // Go to (5).
// (3) Cons string. Check that it's flat.
__ Ldr(x10, FieldMemOperand(subject, ConsString::kSecondOffset));
__ JumpIfNotRoot(x10, Heap::kempty_stringRootIndex, &runtime);
// Replace subject with first string.
__ Ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
+ __ B(&check_underlying);
- // (4) Is subject external? If yes, go to (7).
- __ Bind(&check_underlying);
- // Reload the string type.
- __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset));
- STATIC_ASSERT(kSeqStringTag == 0);
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ TestAndBranchIfAnySet(string_type.X(),
- kStringRepresentationMask,
- &external_string); // Go to (7).
-
- // (5) Sequential string. Load regexp code according to encoding.
+ // (4) Sequential string. Load regexp code according to encoding.
__ Bind(&seq_string);
// Check that the third argument is a positive smi less than the subject
@@ -2083,12 +2079,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (6) Not a long external string? If yes, go to (8).
+ // (5) Long external string? If not, go to (7).
__ Bind(&not_seq_nor_cons);
// Compare flags are still set.
- __ B(ne, &not_long_external); // Go to (8).
+ __ B(ne, &not_long_external); // Go to (7).
- // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (6) External string. Make it, offset-wise, look like a sequential string.
__ Bind(&external_string);
if (masm->emit_debug_code()) {
// Assert that we do not have a cons or slice (indirect strings) here.
@@ -2106,9 +2102,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Move the pointer so that offset-wise, it looks like a sequential string.
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ Sub(subject, subject, SeqTwoByteString::kHeaderSize - kHeapObjectTag);
- __ B(&seq_string); // Go to (5).
+ __ B(&seq_string); // Go to (4).
- // (8) If this is a short external string or not a string, bail out to
+ // (7) If this is a short external string or not a string, bail out to
// runtime.
__ Bind(&not_long_external);
STATIC_ASSERT(kShortExternalStringTag != 0);
@@ -2116,11 +2112,11 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
kShortExternalStringMask | kIsNotStringMask,
&runtime);
- // (9) Sliced string. Replace subject with parent.
+ // (8) Sliced string. Replace subject with parent.
__ Ldr(sliced_string_offset,
UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset));
__ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
- __ B(&check_underlying); // Go to (4).
+ __ B(&check_underlying); // Go to (1).
#endif
}
diff --git a/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc b/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc
index d821462526..f649ba9109 100644
--- a/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc
@@ -530,9 +530,10 @@ void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
IA32OperandGenerator g(selector);
+ InstructionOperand temps[] = {g.TempRegister(eax)};
selector->Emit(opcode, g.DefineAsFixed(node, edx),
g.UseFixed(node->InputAt(0), eax),
- g.UseUnique(node->InputAt(1)));
+ g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
}
void EmitLea(InstructionSelector* selector, Node* result, Node* index,
diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc
index b6cd40d21d..df2d9086ef 100644
--- a/deps/v8/src/compiler/js-generic-lowering.cc
+++ b/deps/v8/src/compiler/js-generic-lowering.cc
@@ -81,117 +81,22 @@ REPLACE_BINARY_OP_IC_CALL(JSDivide, Token::DIV)
REPLACE_BINARY_OP_IC_CALL(JSModulus, Token::MOD)
#undef REPLACE_BINARY_OP_IC_CALL
-
-// These ops are not language mode dependent; we arbitrarily pass Strength::WEAK
-// here.
-#define REPLACE_COMPARE_IC_CALL(op, token) \
- void JSGenericLowering::Lower##op(Node* node) { \
- ReplaceWithCompareIC(node, token); \
- }
-REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ)
-REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE)
-REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT)
-REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT)
-REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT)
-REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT)
-REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE)
-REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE)
-#undef REPLACE_COMPARE_IC_CALL
-
-
#define REPLACE_RUNTIME_CALL(op, fun) \
void JSGenericLowering::Lower##op(Node* node) { \
ReplaceWithRuntimeCall(node, fun); \
}
+REPLACE_RUNTIME_CALL(JSEqual, Runtime::kEqual)
+REPLACE_RUNTIME_CALL(JSNotEqual, Runtime::kNotEqual)
+REPLACE_RUNTIME_CALL(JSStrictEqual, Runtime::kStrictEqual)
+REPLACE_RUNTIME_CALL(JSStrictNotEqual, Runtime::kStrictNotEqual)
+REPLACE_RUNTIME_CALL(JSLessThan, Runtime::kLessThan)
+REPLACE_RUNTIME_CALL(JSGreaterThan, Runtime::kGreaterThan)
+REPLACE_RUNTIME_CALL(JSLessThanOrEqual, Runtime::kLessThanOrEqual)
+REPLACE_RUNTIME_CALL(JSGreaterThanOrEqual, Runtime::kGreaterThanOrEqual)
REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver)
-#undef REPLACE_RUNTIME
-
-
-static CallDescriptor::Flags FlagsForNode(Node* node) {
- CallDescriptor::Flags result = CallDescriptor::kNoFlags;
- if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
- result |= CallDescriptor::kNeedsFrameState;
- }
- return result;
-}
-
-void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
- Callable callable = CodeFactory::CompareIC(isolate(), token);
-
- // Create a new call node asking a CompareIC for help.
- NodeVector inputs(zone());
- inputs.reserve(node->InputCount() + 1);
- inputs.push_back(jsgraph()->HeapConstant(callable.code()));
- inputs.push_back(NodeProperties::GetValueInput(node, 0));
- inputs.push_back(NodeProperties::GetValueInput(node, 1));
- inputs.push_back(NodeProperties::GetContextInput(node));
- // Some comparisons (StrictEqual) don't have an effect, control or frame
- // state inputs, so handle those cases here.
- if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
- inputs.push_back(NodeProperties::GetFrameStateInput(node, 0));
- }
- Node* effect = (node->op()->EffectInputCount() > 0)
- ? NodeProperties::GetEffectInput(node)
- : graph()->start();
- inputs.push_back(effect);
- Node* control = (node->op()->ControlInputCount() > 0)
- ? NodeProperties::GetControlInput(node)
- : graph()->start();
- inputs.push_back(control);
- CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor(
- isolate(), zone(), callable.descriptor(), 0,
- CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node),
- Operator::kNoProperties, MachineType::IntPtr());
- Node* compare =
- graph()->NewNode(common()->Call(desc_compare),
- static_cast<int>(inputs.size()), &inputs.front());
-
- // Decide how the return value from the above CompareIC can be converted into
- // a JavaScript boolean oddball depending on the given token.
- Node* false_value = jsgraph()->FalseConstant();
- Node* true_value = jsgraph()->TrueConstant();
- const Operator* op = nullptr;
- switch (token) {
- case Token::EQ: // a == 0
- case Token::EQ_STRICT:
- op = machine()->WordEqual();
- break;
- case Token::NE: // a != 0 becomes !(a == 0)
- case Token::NE_STRICT:
- op = machine()->WordEqual();
- std::swap(true_value, false_value);
- break;
- case Token::LT: // a < 0
- op = machine()->IntLessThan();
- break;
- case Token::GT: // a > 0 becomes !(a <= 0)
- op = machine()->IntLessThanOrEqual();
- std::swap(true_value, false_value);
- break;
- case Token::LTE: // a <= 0
- op = machine()->IntLessThanOrEqual();
- break;
- case Token::GTE: // a >= 0 becomes !(a < 0)
- op = machine()->IntLessThan();
- std::swap(true_value, false_value);
- break;
- default:
- UNREACHABLE();
- }
- Node* booleanize = graph()->NewNode(op, compare, jsgraph()->ZeroConstant());
-
- // Finally patch the original node to select a boolean.
- NodeProperties::ReplaceUses(node, node, compare, compare, compare);
- node->TrimInputCount(3);
- node->ReplaceInput(0, booleanize);
- node->ReplaceInput(1, true_value);
- node->ReplaceInput(2, false_value);
- NodeProperties::ChangeOp(node,
- common()->Select(MachineRepresentation::kTagged));
-}
-
+#undef REPLACE_RUNTIME_CALL
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags) {
@@ -207,11 +112,12 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
Runtime::FunctionId f,
int nargs_override) {
+ CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
Operator::Properties properties = node->op()->properties();
const Runtime::Function* fun = Runtime::FunctionForId(f);
int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
- CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
- zone(), f, nargs, properties, CallDescriptor::kNeedsFrameState);
+ CallDescriptor* desc =
+ Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties, flags);
Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate()));
Node* arity = jsgraph()->Int32Constant(nargs);
node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
diff --git a/deps/v8/src/compiler/js-generic-lowering.h b/deps/v8/src/compiler/js-generic-lowering.h
index f4acdf6305..5ee759bcc8 100644
--- a/deps/v8/src/compiler/js-generic-lowering.h
+++ b/deps/v8/src/compiler/js-generic-lowering.h
@@ -36,7 +36,6 @@ class JSGenericLowering final : public Reducer {
#undef DECLARE_LOWER
// Helpers to replace existing nodes with a generic call.
- void ReplaceWithCompareIC(Node* node, Token::Value token);
void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags);
void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
diff --git a/deps/v8/src/compiler/x64/instruction-selector-x64.cc b/deps/v8/src/compiler/x64/instruction-selector-x64.cc
index ac0c7f7bf2..d3a2a8e753 100644
--- a/deps/v8/src/compiler/x64/instruction-selector-x64.cc
+++ b/deps/v8/src/compiler/x64/instruction-selector-x64.cc
@@ -763,9 +763,10 @@ void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
X64OperandGenerator g(selector);
- selector->Emit(opcode, g.DefineAsFixed(node, rdx),
- g.UseFixed(node->InputAt(0), rax),
- g.UseUniqueRegister(node->InputAt(1)));
+ InstructionOperand temps[] = {g.TempRegister(rax)};
+ selector->Emit(
+ opcode, g.DefineAsFixed(node, rdx), g.UseFixed(node->InputAt(0), rax),
+ g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
}
} // namespace
diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc
index 1134c9dd68..8114c21fe8 100644
--- a/deps/v8/src/debug/debug-evaluate.cc
+++ b/deps/v8/src/debug/debug-evaluate.cc
@@ -346,6 +346,7 @@ void DebugEvaluate::ContextBuilder::MaterializeContextChain(
// within debug-evaluate.
continue;
}
+ if (value->IsTheHole()) continue; // Value is not initialized yet (in TDZ).
JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
}
}
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc
index 2565c45d31..510b58e723 100644
--- a/deps/v8/src/ia32/code-stubs-ia32.cc
+++ b/deps/v8/src/ia32/code-stubs-ia32.cc
@@ -798,39 +798,37 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ mov(eax, Operand(esp, kSubjectOffset));
__ JumpIfSmi(eax, &runtime);
__ mov(edx, eax); // Make a copy of the original subject string.
- __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
// eax: subject string
// edx: subject string
- // ebx: subject string instance type
// ecx: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
// (1) Sequential two byte? If yes, go to (9).
- // (2) Sequential one byte? If yes, go to (6).
- // (3) Anything but sequential or cons? If yes, go to (7).
- // (4) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (5a) Is subject sequential two byte? If yes, go to (9).
- // (5b) Is subject external? If yes, go to (8).
- // (6) One byte sequential. Load regexp code for one byte.
+ // (2) Sequential one byte? If yes, go to (5).
+ // (3) Sequential or cons? If not, go to (6).
+ // (4) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (5) One byte sequential. Load regexp code for one byte.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (7) Not a long external string? If yes, go to (10).
- // (8) External string. Make it, offset-wise, look like a sequential string.
- // (8a) Is the external string one byte? If yes, go to (6).
- // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
+ // (6) Long external string? If not, go to (10).
+ // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (8) Is the external string one byte? If yes, go to (5).
+ // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
// (10) Short external string or not a string? If yes, bail out to runtime.
- // (11) Sliced string. Replace subject with parent. Go to (5a).
+ // (11) Sliced string. Replace subject with parent. Go to (1).
- Label seq_one_byte_string /* 6 */, seq_two_byte_string /* 9 */,
- external_string /* 8 */, check_underlying /* 5a */,
- not_seq_nor_cons /* 7 */, check_code /* E */,
- not_long_external /* 10 */;
+ Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */,
+ external_string /* 7 */, check_underlying /* 1 */,
+ not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */;
+ __ bind(&check_underlying);
// (1) Sequential two byte? If yes, go to (9).
+ __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+
__ and_(ebx, kIsNotStringMask |
kStringRepresentationMask |
kStringEncodingMask |
@@ -838,14 +836,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string); // Go to (9).
- // (2) Sequential one byte? If yes, go to (6).
+ // (2) Sequential one byte? If yes, go to (5).
// Any other sequential string must be one byte.
__ and_(ebx, Immediate(kIsNotStringMask |
kStringRepresentationMask |
kShortExternalStringMask));
- __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (6).
+ __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5).
- // (3) Anything but sequential or cons? If yes, go to (7).
+ // (3) Sequential or cons? If not, go to (6).
// We check whether the subject string is a cons, since sequential strings
// have already been covered.
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
@@ -853,32 +851,19 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
__ cmp(ebx, Immediate(kExternalStringTag));
- __ j(greater_equal, &not_seq_nor_cons); // Go to (7).
+ __ j(greater_equal, &not_seq_nor_cons); // Go to (6).
// (4) Cons string. Check that it's flat.
// Replace subject with first string and reload instance type.
__ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string());
__ j(not_equal, &runtime);
__ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
- __ bind(&check_underlying);
- __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
-
- // (5a) Is subject sequential two byte? If yes, go to (9).
- __ test_b(ebx, kStringRepresentationMask | kStringEncodingMask);
- STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
- __ j(zero, &seq_two_byte_string); // Go to (9).
- // (5b) Is subject external? If yes, go to (8).
- __ test_b(ebx, kStringRepresentationMask);
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ j(not_zero, &external_string); // Go to (8).
+ __ jmp(&check_underlying);
// eax: sequential subject string (or look-alike, external string)
// edx: original subject string
// ecx: RegExp data (FixedArray)
- // (6) One byte sequential. Load regexp code for one byte.
+ // (5) One byte sequential. Load regexp code for one byte.
__ bind(&seq_one_byte_string);
// Load previous index and check range before edx is overwritten. We have
// to use edx instead of eax here because it might have been only made to
@@ -1105,12 +1090,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (7) Not a long external string? If yes, go to (10).
+ // (6) Long external string? If not, go to (10).
__ bind(&not_seq_nor_cons);
// Compare flags are still set from (3).
__ j(greater, &not_long_external, Label::kNear); // Go to (10).
- // (8) External string. Short external strings have been ruled out.
+ // (7) External string. Short external strings have been ruled out.
__ bind(&external_string);
// Reload instance type.
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -1126,14 +1111,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
STATIC_ASSERT(kTwoByteStringTag == 0);
- // (8a) Is the external string one byte? If yes, go to (6).
+ // (8) Is the external string one byte? If yes, go to (5).
__ test_b(ebx, kStringEncodingMask);
- __ j(not_zero, &seq_one_byte_string); // Goto (6).
+ __ j(not_zero, &seq_one_byte_string); // Go to (5).
// eax: sequential subject string (or look-alike, external string)
// edx: original subject string
// ecx: RegExp data (FixedArray)
- // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
+ // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
__ bind(&seq_two_byte_string);
// Load previous index and check range before edx is overwritten. We have
// to use edx instead of eax here because it might have been only made to
@@ -1153,11 +1138,11 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag));
__ j(not_zero, &runtime);
- // (11) Sliced string. Replace subject with parent. Go to (5a).
+ // (11) Sliced string. Replace subject with parent. Go to (1).
// Load offset into edi and replace subject string with parent.
__ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset));
__ mov(eax, FieldOperand(eax, SlicedString::kParentOffset));
- __ jmp(&check_underlying); // Go to (5a).
+ __ jmp(&check_underlying); // Go to (1).
#endif // V8_INTERPRETED_REGEXP
}
@@ -1442,21 +1427,24 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
}
__ bind(&runtime_call);
- // Push arguments below the return address.
- __ pop(ecx);
- __ push(edx);
- __ push(eax);
-
- // Figure out which native to call and setup the arguments.
if (cc == equal) {
- __ push(ecx);
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(edx);
+ __ Push(eax);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ sub(eax, Immediate(isolate()->factory()->true_value()));
+ __ Ret();
} else {
+ // Push arguments below the return address.
+ __ pop(ecx);
+ __ push(edx);
+ __ push(eax);
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
-
- // Restore return address on the stack.
__ push(ecx);
-
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
// tagged as a small integer.
__ TailCallRuntime(Runtime::kCompare);
diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc
index 4c2b20ca1b..c0b3e49338 100644
--- a/deps/v8/src/ic/ic.cc
+++ b/deps/v8/src/ic/ic.cc
@@ -573,13 +573,21 @@ static bool MigrateDeprecated(Handle<Object> object) {
return true;
}
-
-void IC::ConfigureVectorState(IC::State new_state) {
+void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
DCHECK(UseVector());
if (new_state == PREMONOMORPHIC) {
nexus()->ConfigurePremonomorphic();
} else if (new_state == MEGAMORPHIC) {
- nexus()->ConfigureMegamorphic();
+ if (kind() == Code::LOAD_IC || kind() == Code::STORE_IC) {
+ nexus()->ConfigureMegamorphic();
+ } else if (kind() == Code::KEYED_LOAD_IC) {
+ KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
+ nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
+ } else {
+ DCHECK(kind() == Code::KEYED_STORE_IC);
+ KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
+ nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
+ }
} else {
UNREACHABLE();
}
@@ -662,7 +670,7 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
// Rewrite to the generic keyed load stub.
if (FLAG_use_ic) {
DCHECK(UseVector());
- ConfigureVectorState(MEGAMORPHIC);
+ ConfigureVectorState(MEGAMORPHIC, name);
TRACE_IC("LoadIC", name);
TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
}
@@ -853,7 +861,7 @@ void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
CopyICToMegamorphicCache(name);
}
if (UseVector()) {
- ConfigureVectorState(MEGAMORPHIC);
+ ConfigureVectorState(MEGAMORPHIC, name);
} else {
set_target(*megamorphic_stub());
}
@@ -1012,7 +1020,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
if (state() == UNINITIALIZED) {
// This is the first time we execute this inline cache. Set the target to
// the pre monomorphic stub to delay setting the monomorphic state.
- ConfigureVectorState(PREMONOMORPHIC);
+ ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
TRACE_IC("LoadIC", lookup->name());
return;
}
@@ -1378,7 +1386,7 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
if (!is_vector_set() || stub.is_null()) {
Code* generic = *megamorphic_stub();
if (!stub.is_null() && *stub == generic) {
- ConfigureVectorState(MEGAMORPHIC);
+ ConfigureVectorState(MEGAMORPHIC, key);
TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
}
@@ -1471,7 +1479,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
// Rewrite to the generic keyed store stub.
if (FLAG_use_ic) {
if (UseVector()) {
- ConfigureVectorState(MEGAMORPHIC);
+ ConfigureVectorState(MEGAMORPHIC, name);
} else if (!AddressIsDeoptimizedCode()) {
set_target(*megamorphic_stub());
}
@@ -1645,7 +1653,7 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
if (state() == UNINITIALIZED) {
// This is the first time we execute this inline cache. Set the target to
// the pre monomorphic stub to delay setting the monomorphic state.
- ConfigureVectorState(PREMONOMORPHIC);
+ ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
TRACE_IC("StoreIC", lookup->name());
return;
}
@@ -2072,7 +2080,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
JSReceiver::MAY_BE_STORE_FROM_KEYED),
Object);
if (!is_vector_set()) {
- ConfigureVectorState(MEGAMORPHIC);
+ ConfigureVectorState(MEGAMORPHIC, key);
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
"unhandled internalized string key");
TRACE_IC("StoreIC", key);
@@ -2147,7 +2155,7 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
if (!is_vector_set() || stub.is_null()) {
Code* megamorphic = *megamorphic_stub();
if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) {
- ConfigureVectorState(MEGAMORPHIC);
+ ConfigureVectorState(MEGAMORPHIC, key);
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
*stub == megamorphic ? "set generic" : "slow stub");
}
diff --git a/deps/v8/src/ic/ic.h b/deps/v8/src/ic/ic.h
index 2ce182b76e..0a324a8205 100644
--- a/deps/v8/src/ic/ic.h
+++ b/deps/v8/src/ic/ic.h
@@ -112,7 +112,7 @@ class IC {
}
// Configure for most states.
- void ConfigureVectorState(IC::State new_state);
+ void ConfigureVectorState(IC::State new_state, Handle<Object> key);
// Configure the vector for MONOMORPHIC.
void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Code> handler);
@@ -296,10 +296,6 @@ class CallIC : public IC {
class LoadIC : public IC {
public:
- static ExtraICState ComputeExtraICState(TypeofMode typeof_mode) {
- return LoadICState(typeof_mode).GetExtraICState();
- }
-
TypeofMode typeof_mode() const {
return LoadICState::GetTypeofMode(extra_ic_state());
}
@@ -364,20 +360,6 @@ class LoadIC : public IC {
class KeyedLoadIC : public LoadIC {
public:
- // ExtraICState bits (building on IC)
- class IcCheckTypeField
- : public BitField<IcCheckType, LoadICState::kNextBitFieldOffset, 1> {};
-
- static ExtraICState ComputeExtraICState(TypeofMode typeof_mode,
- IcCheckType key_type) {
- return LoadICState(typeof_mode).GetExtraICState() |
- IcCheckTypeField::encode(key_type);
- }
-
- static IcCheckType GetKeyType(ExtraICState extra_state) {
- return IcCheckTypeField::decode(extra_state);
- }
-
KeyedLoadIC(FrameDepth depth, Isolate* isolate,
KeyedLoadICNexus* nexus = NULL)
: LoadIC(depth, isolate, nexus) {
diff --git a/deps/v8/src/interpreter/interpreter.cc b/deps/v8/src/interpreter/interpreter.cc
index 43a7ead281..eb883427bb 100644
--- a/deps/v8/src/interpreter/interpreter.cc
+++ b/deps/v8/src/interpreter/interpreter.cc
@@ -1139,7 +1139,7 @@ void Interpreter::DoNewWide(InterpreterAssembler* assembler) {
//
// Test if the value in the <src> register equals the accumulator.
void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterEquals, assembler);
+ DoBinaryOp(Runtime::kEqual, assembler);
}
@@ -1147,7 +1147,7 @@ void Interpreter::DoTestEqual(InterpreterAssembler* assembler) {
//
// Test if the value in the <src> register is not equal to the accumulator.
void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterNotEquals, assembler);
+ DoBinaryOp(Runtime::kNotEqual, assembler);
}
@@ -1155,7 +1155,7 @@ void Interpreter::DoTestNotEqual(InterpreterAssembler* assembler) {
//
// Test if the value in the <src> register is strictly equal to the accumulator.
void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterStrictEquals, assembler);
+ DoBinaryOp(Runtime::kStrictEqual, assembler);
}
@@ -1164,7 +1164,7 @@ void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
// Test if the value in the <src> register is not strictly equal to the
// accumulator.
void Interpreter::DoTestNotEqualStrict(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterStrictNotEquals, assembler);
+ DoBinaryOp(Runtime::kStrictNotEqual, assembler);
}
@@ -1172,7 +1172,7 @@ void Interpreter::DoTestNotEqualStrict(InterpreterAssembler* assembler) {
//
// Test if the value in the <src> register is less than the accumulator.
void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterLessThan, assembler);
+ DoBinaryOp(Runtime::kLessThan, assembler);
}
@@ -1180,7 +1180,7 @@ void Interpreter::DoTestLessThan(InterpreterAssembler* assembler) {
//
// Test if the value in the <src> register is greater than the accumulator.
void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterGreaterThan, assembler);
+ DoBinaryOp(Runtime::kGreaterThan, assembler);
}
@@ -1189,7 +1189,7 @@ void Interpreter::DoTestGreaterThan(InterpreterAssembler* assembler) {
// Test if the value in the <src> register is less than or equal to the
// accumulator.
void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterLessThanOrEqual, assembler);
+ DoBinaryOp(Runtime::kLessThanOrEqual, assembler);
}
@@ -1198,7 +1198,7 @@ void Interpreter::DoTestLessThanOrEqual(InterpreterAssembler* assembler) {
// Test if the value in the <src> register is greater than or equal to the
// accumulator.
void Interpreter::DoTestGreaterThanOrEqual(InterpreterAssembler* assembler) {
- DoBinaryOp(Runtime::kInterpreterGreaterThanOrEqual, assembler);
+ DoBinaryOp(Runtime::kGreaterThanOrEqual, assembler);
}
diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc
index 8eb8b71b39..8116f14d30 100644
--- a/deps/v8/src/isolate.cc
+++ b/deps/v8/src/isolate.cc
@@ -2512,6 +2512,7 @@ bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
}
bool Isolate::IsArraySpeciesLookupChainIntact() {
+ if (!FLAG_harmony_species) return true;
// Note: It would be nice to have debug checks to make sure that the
// species protector is accurate, but this would be hard to do for most of
// what the protector stands for:
@@ -2530,6 +2531,7 @@ bool Isolate::IsArraySpeciesLookupChainIntact() {
}
void Isolate::InvalidateArraySpeciesProtector() {
+ if (!FLAG_harmony_species) return;
DCHECK(factory()->species_protector()->value()->IsSmi());
DCHECK(IsArraySpeciesLookupChainIntact());
PropertyCell::SetValueWithInvalidation(
diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc
index 77dbcb122d..541e73e2fa 100644
--- a/deps/v8/src/mips/code-stubs-mips.cc
+++ b/deps/v8/src/mips/code-stubs-mips.cc
@@ -718,13 +718,21 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
// Never falls through to here.
__ bind(&slow);
- // Prepare for call to builtin. Push object pointers, a0 (lhs) first,
- // a1 (rhs) second.
- __ Push(lhs, rhs);
- // Figure out which native to call and setup the arguments.
if (cc == eq) {
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(lhs, rhs);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ LoadRoot(a0, Heap::kTrueValueRootIndex);
+ __ Ret(USE_DELAY_SLOT);
+ __ subu(v0, v0, a0); // In delay slot.
} else {
+ // Prepare for call to builtin. Push object pointers, a0 (lhs) first,
+ // a1 (rhs) second.
+ __ Push(lhs, rhs);
int ncr; // NaN compare result.
if (cc == lt || cc == le) {
ncr = GREATER;
@@ -1597,7 +1605,6 @@ void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) {
masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
}
-
void RegExpExecStub::Generate(MacroAssembler* masm) {
// Just jump directly to runtime if native RegExp is not selected at compile
// time or if regexp entry in generated code is turned off runtime switch or
@@ -1630,8 +1637,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Ensure that a RegExp stack is allocated.
ExternalReference address_of_regexp_stack_memory_address =
- ExternalReference::address_of_regexp_stack_memory_address(
- isolate());
+ ExternalReference::address_of_regexp_stack_memory_address(isolate());
ExternalReference address_of_regexp_stack_memory_size =
ExternalReference::address_of_regexp_stack_memory_size(isolate());
__ li(a0, Operand(address_of_regexp_stack_memory_size));
@@ -1683,34 +1689,33 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ lw(subject, MemOperand(sp, kSubjectOffset));
__ JumpIfSmi(subject, &runtime);
__ mov(a3, subject); // Make a copy of the original subject string.
- __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
// subject: subject string
// a3: subject string
- // a0: subject string instance type
// regexp_data: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
- // (1) Sequential string? If yes, go to (5).
- // (2) Anything but sequential or cons? If yes, go to (6).
- // (3) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (4) Is subject external? If yes, go to (7).
- // (5) Sequential string. Load regexp code according to encoding.
+ // (1) Sequential string? If yes, go to (4).
+ // (2) Sequential or cons? If not, go to (5).
+ // (3) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (4) Sequential string. Load regexp code according to encoding.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (6) Not a long external string? If yes, go to (8).
- // (7) External string. Make it, offset-wise, look like a sequential string.
- // Go to (5).
- // (8) Short external string or not a string? If yes, bail out to runtime.
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (5) Long external string? If not, go to (7).
+ // (6) External string. Make it, offset-wise, look like a sequential string.
+ // Go to (4).
+ // (7) Short external string or not a string? If yes, bail out to runtime.
+ // (8) Sliced string. Replace subject with parent. Go to (1).
+
+ Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */,
+ not_seq_nor_cons /* 5 */, not_long_external /* 7 */;
- Label seq_string /* 5 */, external_string /* 7 */,
- check_underlying /* 4 */, not_seq_nor_cons /* 6 */,
- not_long_external /* 8 */;
+ __ bind(&check_underlying);
+ __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
+ __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
- // (1) Sequential string? If yes, go to (5).
+ // (1) Sequential string? If yes, go to (4).
__ And(a1,
a0,
Operand(kIsNotStringMask |
@@ -1719,12 +1724,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
__ Branch(&seq_string, eq, a1, Operand(zero_reg)); // Go to (5).
- // (2) Anything but sequential or cons? If yes, go to (6).
+ // (2) Sequential or cons? If not, go to (5).
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
- // Go to (6).
+ // Go to (5).
__ Branch(&not_seq_nor_cons, ge, a1, Operand(kExternalStringTag));
// (3) Cons string. Check that it's flat.
@@ -1733,19 +1738,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ LoadRoot(a1, Heap::kempty_stringRootIndex);
__ Branch(&runtime, ne, a0, Operand(a1));
__ lw(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
+ __ jmp(&check_underlying);
- // (4) Is subject external? If yes, go to (7).
- __ bind(&check_underlying);
- __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
- STATIC_ASSERT(kSeqStringTag == 0);
- __ And(at, a0, Operand(kStringRepresentationMask));
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ Branch(&external_string, ne, at, Operand(zero_reg)); // Go to (7).
-
- // (5) Sequential string. Load regexp code according to encoding.
+ // (4) Sequential string. Load regexp code according to encoding.
__ bind(&seq_string);
// subject: sequential subject string (or look-alike, external string)
// a3: original subject string
@@ -1987,12 +1982,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (6) Not a long external string? If yes, go to (8).
+ // (5) Long external string? If not, go to (7).
__ bind(&not_seq_nor_cons);
- // Go to (8).
+ // Go to (7).
__ Branch(&not_long_external, gt, a1, Operand(kExternalStringTag));
- // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (6) External string. Make it, offset-wise, look like a sequential string.
__ bind(&external_string);
__ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
@@ -2014,13 +2009,13 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
SeqTwoByteString::kHeaderSize - kHeapObjectTag);
__ jmp(&seq_string); // Go to (5).
- // (8) Short external string or not a string? If yes, bail out to runtime.
+ // (7) Short external string or not a string? If yes, bail out to runtime.
__ bind(&not_long_external);
STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
__ And(at, a1, Operand(kIsNotStringMask | kShortExternalStringMask));
__ Branch(&runtime, ne, at, Operand(zero_reg));
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (8) Sliced string. Replace subject with parent. Go to (4).
// Load offset into t0 and replace subject string with parent.
__ lw(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset));
__ sra(t0, t0, kSmiTagSize);
diff --git a/deps/v8/src/mips64/code-stubs-mips64.cc b/deps/v8/src/mips64/code-stubs-mips64.cc
index bde5531077..28812ad997 100644
--- a/deps/v8/src/mips64/code-stubs-mips64.cc
+++ b/deps/v8/src/mips64/code-stubs-mips64.cc
@@ -715,13 +715,21 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
// Never falls through to here.
__ bind(&slow);
- // Prepare for call to builtin. Push object pointers, a0 (lhs) first,
- // a1 (rhs) second.
- __ Push(lhs, rhs);
- // Figure out which native to call and setup the arguments.
if (cc == eq) {
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(lhs, rhs);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ LoadRoot(a0, Heap::kTrueValueRootIndex);
+ __ Ret(USE_DELAY_SLOT);
+ __ subu(v0, v0, a0); // In delay slot.
} else {
+ // Prepare for call to builtin. Push object pointers, a0 (lhs) first,
+ // a1 (rhs) second.
+ __ Push(lhs, rhs);
int ncr; // NaN compare result.
if (cc == lt || cc == le) {
ncr = GREATER;
@@ -1678,50 +1686,51 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ ld(subject, MemOperand(sp, kSubjectOffset));
__ JumpIfSmi(subject, &runtime);
__ mov(a3, subject); // Make a copy of the original subject string.
- __ ld(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
+
// subject: subject string
// a3: subject string
- // a0: subject string instance type
// regexp_data: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
- // (1) Sequential string? If yes, go to (5).
- // (2) Anything but sequential or cons? If yes, go to (6).
- // (3) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (4) Is subject external? If yes, go to (7).
- // (5) Sequential string. Load regexp code according to encoding.
+ // (1) Sequential string? If yes, go to (4).
+ // (2) Sequential or cons? If not, go to (5).
+ // (3) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (4) Sequential string. Load regexp code according to encoding.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (6) Not a long external string? If yes, go to (8).
- // (7) External string. Make it, offset-wise, look like a sequential string.
- // Go to (5).
- // (8) Short external string or not a string? If yes, bail out to runtime.
- // (9) Sliced string. Replace subject with parent. Go to (4).
-
- Label check_underlying; // (4)
- Label seq_string; // (5)
- Label not_seq_nor_cons; // (6)
- Label external_string; // (7)
- Label not_long_external; // (8)
-
- // (1) Sequential string? If yes, go to (5).
+ // (5) Long external string? If not, go to (7).
+ // (6) External string. Make it, offset-wise, look like a sequential string.
+ // Go to (4).
+ // (7) Short external string or not a string? If yes, bail out to runtime.
+ // (8) Sliced string. Replace subject with parent. Go to (1).
+
+ Label check_underlying; // (1)
+ Label seq_string; // (4)
+ Label not_seq_nor_cons; // (5)
+ Label external_string; // (6)
+ Label not_long_external; // (7)
+
+ __ bind(&check_underlying);
+ __ ld(a2, FieldMemOperand(subject, HeapObject::kMapOffset));
+ __ lbu(a0, FieldMemOperand(a2, Map::kInstanceTypeOffset));
+
+ // (1) Sequential string? If yes, go to (4).
__ And(a1,
a0,
Operand(kIsNotStringMask |
kStringRepresentationMask |
kShortExternalStringMask));
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
- __ Branch(&seq_string, eq, a1, Operand(zero_reg)); // Go to (5).
+ __ Branch(&seq_string, eq, a1, Operand(zero_reg)); // Go to (4).
- // (2) Anything but sequential or cons? If yes, go to (6).
+ // (2) Sequential or cons? If not, go to (5).
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
- // Go to (6).
+ // Go to (5).
__ Branch(&not_seq_nor_cons, ge, a1, Operand(kExternalStringTag));
// (3) Cons string. Check that it's flat.
@@ -1730,19 +1739,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ LoadRoot(a1, Heap::kempty_stringRootIndex);
__ Branch(&runtime, ne, a0, Operand(a1));
__ ld(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
+ __ jmp(&check_underlying);
- // (4) Is subject external? If yes, go to (7).
- __ bind(&check_underlying);
- __ ld(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
- STATIC_ASSERT(kSeqStringTag == 0);
- __ And(at, a0, Operand(kStringRepresentationMask));
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ Branch(&external_string, ne, at, Operand(zero_reg)); // Go to (7).
-
- // (5) Sequential string. Load regexp code according to encoding.
+ // (4) Sequential string. Load regexp code according to encoding.
__ bind(&seq_string);
// subject: sequential subject string (or look-alike, external string)
// a3: original subject string
@@ -1985,12 +1984,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (6) Not a long external string? If yes, go to (8).
+ // (5) Long external string? If not, go to (7).
__ bind(&not_seq_nor_cons);
- // Go to (8).
+ // Go to (7).
__ Branch(&not_long_external, gt, a1, Operand(kExternalStringTag));
- // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (6) External string. Make it, offset-wise, look like a sequential string.
__ bind(&external_string);
__ ld(a0, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset));
@@ -2010,20 +2009,20 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ Dsubu(subject,
subject,
SeqTwoByteString::kHeaderSize - kHeapObjectTag);
- __ jmp(&seq_string); // Go to (5).
+ __ jmp(&seq_string); // Go to (4).
- // (8) Short external string or not a string? If yes, bail out to runtime.
+ // (7) Short external string or not a string? If yes, bail out to runtime.
__ bind(&not_long_external);
STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
__ And(at, a1, Operand(kIsNotStringMask | kShortExternalStringMask));
__ Branch(&runtime, ne, at, Operand(zero_reg));
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (8) Sliced string. Replace subject with parent. Go to (4).
// Load offset into t0 and replace subject string with parent.
__ ld(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset));
__ SmiUntag(t0);
__ ld(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
- __ jmp(&check_underlying); // Go to (4).
+ __ jmp(&check_underlying); // Go to (1).
#endif // V8_INTERPRETED_REGEXP
}
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index 1abc7ebf07..e00478a6af 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -1353,6 +1353,10 @@ int HeapNumber::get_sign() {
bool Simd128Value::Equals(Simd128Value* that) {
+ // TODO(bmeurer): This doesn't match the SIMD.js specification, but it seems
+ // to be consistent with what the CompareICStub does, and what is tested in
+ // the current SIMD.js testsuite.
+ if (this == that) return true;
#define SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \
if (this->Is##Type()) { \
if (!that->Is##Type()) return false; \
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 67a5963831..f577d5e4d3 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -13715,7 +13715,9 @@ void JSFunction::CalculateInstanceSizeForDerivedClass(
for (PrototypeIterator iter(isolate, this,
PrototypeIterator::START_AT_RECEIVER);
!iter.IsAtEnd(); iter.Advance()) {
- JSFunction* func = iter.GetCurrent<JSFunction>();
+ JSReceiver* current = iter.GetCurrent<JSReceiver>();
+ if (!current->IsJSFunction()) break;
+ JSFunction* func = JSFunction::cast(current);
SharedFunctionInfo* shared = func->shared();
expected_nof_properties += shared->expected_nof_properties();
if (!IsSubclassConstructor(shared->kind())) {
@@ -17347,6 +17349,16 @@ void HashTable<Derived, Shape, Key>::Rehash(Key key) {
}
}
}
+ // Wipe deleted entries.
+ Heap* heap = GetHeap();
+ Object* the_hole = heap->the_hole_value();
+ Object* undefined = heap->undefined_value();
+ for (uint32_t current = 0; current < capacity; current++) {
+ if (get(EntryToIndex(current)) == the_hole) {
+ set(EntryToIndex(current), undefined);
+ }
+ }
+ SetNumberOfDeletedElements(0);
}
@@ -18707,6 +18719,12 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
return table;
}
+ // Rehash if more than 25% of the entries are deleted entries.
+ // TODO(jochen): Consider to shrink the fixed array in place.
+ if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
+ table->Rehash(isolate->factory()->undefined_value());
+ }
+
// Check whether the hash table should be extended.
table = EnsureCapacity(table, 1, key);
table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index a3d6a72882..61c6e5ebe1 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -9292,9 +9292,6 @@ class ExternalString: public String {
static const int kResourceDataOffset = kResourceOffset + kPointerSize;
static const int kSize = kResourceDataOffset + kPointerSize;
- static const int kMaxShortLength =
- (kShortSize - SeqString::kHeaderSize) / kCharSize;
-
// Return whether external string is short (data pointer is not cached).
inline bool is_short();
diff --git a/deps/v8/src/ppc/code-stubs-ppc.cc b/deps/v8/src/ppc/code-stubs-ppc.cc
index f6befb269a..03c73af503 100644
--- a/deps/v8/src/ppc/code-stubs-ppc.cc
+++ b/deps/v8/src/ppc/code-stubs-ppc.cc
@@ -698,11 +698,19 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
__ bind(&slow);
- __ Push(lhs, rhs);
- // Figure out which native to call and setup the arguments.
if (cc == eq) {
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+ __ Push(lhs, rhs);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ LoadRoot(r4, Heap::kTrueValueRootIndex);
+ __ sub(r3, r3, r4);
+ __ Ret();
} else {
+ __ Push(lhs, rhs);
int ncr; // NaN compare result
if (cc == lt || cc == le) {
ncr = GREATER;
@@ -1633,48 +1641,49 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ LoadP(subject, MemOperand(sp, kSubjectOffset));
__ JumpIfSmi(subject, &runtime);
__ mr(r6, subject); // Make a copy of the original subject string.
- __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
// subject: subject string
// r6: subject string
- // r3: subject string instance type
// regexp_data: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
- // (1) Sequential string? If yes, go to (5).
- // (2) Anything but sequential or cons? If yes, go to (6).
- // (3) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (4) Is subject external? If yes, go to (7).
- // (5) Sequential string. Load regexp code according to encoding.
+ // (1) Sequential string? If yes, go to (4).
+ // (2) Sequential or cons? If not, go to (5).
+ // (3) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (4) Sequential string. Load regexp code according to encoding.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (6) Not a long external string? If yes, go to (8).
- // (7) External string. Make it, offset-wise, look like a sequential string.
- // Go to (5).
- // (8) Short external string or not a string? If yes, bail out to runtime.
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (5) Long external string? If not, go to (7).
+ // (6) External string. Make it, offset-wise, look like a sequential string.
+ // Go to (4).
+ // (7) Short external string or not a string? If yes, bail out to runtime.
+ // (8) Sliced string. Replace subject with parent. Go to (1).
+
+ Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */,
+ not_seq_nor_cons /* 5 */, not_long_external /* 7 */;
- Label seq_string /* 5 */, external_string /* 7 */, check_underlying /* 4 */,
- not_seq_nor_cons /* 6 */, not_long_external /* 8 */;
+ __ bind(&check_underlying);
+ __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
+ __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+
+ // (1) Sequential string? If yes, go to (4).
- // (1) Sequential string? If yes, go to (5).
STATIC_ASSERT((kIsNotStringMask | kStringRepresentationMask |
kShortExternalStringMask) == 0x93);
__ andi(r4, r3, Operand(kIsNotStringMask | kStringRepresentationMask |
kShortExternalStringMask));
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
- __ beq(&seq_string, cr0); // Go to (5).
+ __ beq(&seq_string, cr0); // Go to (4).
- // (2) Anything but sequential or cons? If yes, go to (6).
+ // (2) Sequential or cons? If not, go to (5).
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
STATIC_ASSERT(kExternalStringTag < 0xffffu);
__ cmpi(r4, Operand(kExternalStringTag));
- __ bge(&not_seq_nor_cons); // Go to (6).
+ __ bge(&not_seq_nor_cons); // Go to (5).
// (3) Cons string. Check that it's flat.
// Replace subject with first string and reload instance type.
@@ -1682,20 +1691,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ CompareRoot(r3, Heap::kempty_stringRootIndex);
__ bne(&runtime);
__ LoadP(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
+ __ b(&check_underlying);
- // (4) Is subject external? If yes, go to (7).
- __ bind(&check_underlying);
- __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
- __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
- STATIC_ASSERT(kSeqStringTag == 0);
- STATIC_ASSERT(kStringRepresentationMask == 3);
- __ andi(r0, r3, Operand(kStringRepresentationMask));
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ bne(&external_string, cr0); // Go to (7).
-
- // (5) Sequential string. Load regexp code according to encoding.
+ // (4) Sequential string. Load regexp code according to encoding.
__ bind(&seq_string);
// subject: sequential subject string (or look-alike, external string)
// r6: original subject string
@@ -1928,12 +1926,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (6) Not a long external string? If yes, go to (8).
+ // (5) Long external string? If not, go to (7).
__ bind(&not_seq_nor_cons);
// Compare flags are still set.
- __ bgt(&not_long_external); // Go to (8).
+ __ bgt(&not_long_external); // Go to (7).
- // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (6) External string. Make it, offset-wise, look like a sequential string.
__ bind(&external_string);
__ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
@@ -1950,15 +1948,15 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ subi(subject, subject,
Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
- __ b(&seq_string); // Go to (5).
+ __ b(&seq_string); // Go to (4).
- // (8) Short external string or not a string? If yes, bail out to runtime.
+ // (7) Short external string or not a string? If yes, bail out to runtime.
__ bind(&not_long_external);
STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag != 0);
__ andi(r0, r4, Operand(kIsNotStringMask | kShortExternalStringMask));
__ bne(&runtime, cr0);
- // (9) Sliced string. Replace subject with parent. Go to (4).
+ // (8) Sliced string. Replace subject with parent. Go to (4).
// Load offset into r11 and replace subject string with parent.
__ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset));
__ SmiUntag(r11);
diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc
index cbacb554ad..7150a8b287 100644
--- a/deps/v8/src/runtime/runtime-interpreter.cc
+++ b/deps/v8/src/runtime/runtime-interpreter.cc
@@ -16,109 +16,6 @@
namespace v8 {
namespace internal {
-
-RUNTIME_FUNCTION(Runtime_InterpreterEquals) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::Equals(x, y);
- if (result.IsJust()) {
- return isolate->heap()->ToBoolean(result.FromJust());
- } else {
- return isolate->heap()->exception();
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterNotEquals) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::Equals(x, y);
- if (result.IsJust()) {
- return isolate->heap()->ToBoolean(!result.FromJust());
- } else {
- return isolate->heap()->exception();
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterLessThan) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::LessThan(x, y);
- if (result.IsJust()) {
- return isolate->heap()->ToBoolean(result.FromJust());
- } else {
- return isolate->heap()->exception();
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterGreaterThan) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::GreaterThan(x, y);
- if (result.IsJust()) {
- return isolate->heap()->ToBoolean(result.FromJust());
- } else {
- return isolate->heap()->exception();
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterLessThanOrEqual) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::LessThanOrEqual(x, y);
- if (result.IsJust()) {
- return isolate->heap()->ToBoolean(result.FromJust());
- } else {
- return isolate->heap()->exception();
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterGreaterThanOrEqual) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::GreaterThanOrEqual(x, y);
- if (result.IsJust()) {
- return isolate->heap()->ToBoolean(result.FromJust());
- } else {
- return isolate->heap()->exception();
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterStrictEquals) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_CHECKED(Object, x, 0);
- CONVERT_ARG_CHECKED(Object, y, 1);
- return isolate->heap()->ToBoolean(x->StrictEquals(y));
-}
-
-
-RUNTIME_FUNCTION(Runtime_InterpreterStrictNotEquals) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_CHECKED(Object, x, 0);
- CONVERT_ARG_CHECKED(Object, y, 1);
- return isolate->heap()->ToBoolean(!x->StrictEquals(y));
-}
-
-
RUNTIME_FUNCTION(Runtime_InterpreterToBoolean) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());
diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc
index 415920d6c6..45a49925bd 100644
--- a/deps/v8/src/runtime/runtime-object.cc
+++ b/deps/v8/src/runtime/runtime-object.cc
@@ -1073,28 +1073,6 @@ RUNTIME_FUNCTION(Runtime_ToName) {
}
-RUNTIME_FUNCTION(Runtime_Equals) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
- Maybe<bool> result = Object::Equals(x, y);
- if (!result.IsJust()) return isolate->heap()->exception();
- // TODO(bmeurer): Change this at some point to return true/false instead.
- return Smi::FromInt(result.FromJust() ? EQUAL : NOT_EQUAL);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StrictEquals) {
- SealHandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_CHECKED(Object, x, 0);
- CONVERT_ARG_CHECKED(Object, y, 1);
- // TODO(bmeurer): Change this at some point to return true/false instead.
- return Smi::FromInt(x->StrictEquals(y) ? EQUAL : NOT_EQUAL);
-}
-
-
RUNTIME_FUNCTION(Runtime_SameValue) {
SealHandleScope scope(isolate);
DCHECK_EQ(2, args.length());
diff --git a/deps/v8/src/runtime/runtime-operators.cc b/deps/v8/src/runtime/runtime-operators.cc
index 02fd0cd332..e55ab7c542 100644
--- a/deps/v8/src/runtime/runtime-operators.cc
+++ b/deps/v8/src/runtime/runtime-operators.cc
@@ -140,5 +140,81 @@ RUNTIME_FUNCTION(Runtime_BitwiseXor) {
return *result;
}
+RUNTIME_FUNCTION(Runtime_Equal) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
+ Maybe<bool> result = Object::Equals(x, y);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+}
+
+RUNTIME_FUNCTION(Runtime_NotEqual) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
+ Maybe<bool> result = Object::Equals(x, y);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(!result.FromJust());
+}
+
+RUNTIME_FUNCTION(Runtime_StrictEqual) {
+ SealHandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_CHECKED(Object, x, 0);
+ CONVERT_ARG_CHECKED(Object, y, 1);
+ return isolate->heap()->ToBoolean(x->StrictEquals(y));
+}
+
+RUNTIME_FUNCTION(Runtime_StrictNotEqual) {
+ SealHandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_CHECKED(Object, x, 0);
+ CONVERT_ARG_CHECKED(Object, y, 1);
+ return isolate->heap()->ToBoolean(!x->StrictEquals(y));
+}
+
+RUNTIME_FUNCTION(Runtime_LessThan) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
+ Maybe<bool> result = Object::LessThan(x, y);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+}
+
+RUNTIME_FUNCTION(Runtime_GreaterThan) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
+ Maybe<bool> result = Object::GreaterThan(x, y);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+}
+
+RUNTIME_FUNCTION(Runtime_LessThanOrEqual) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
+ Maybe<bool> result = Object::LessThanOrEqual(x, y);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+}
+
+RUNTIME_FUNCTION(Runtime_GreaterThanOrEqual) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
+ Maybe<bool> result = Object::GreaterThanOrEqual(x, y);
+ if (!result.IsJust()) return isolate->heap()->exception();
+ return isolate->heap()->ToBoolean(result.FromJust());
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h
index 3b97bb2b36..7019c3bf04 100644
--- a/deps/v8/src/runtime/runtime.h
+++ b/deps/v8/src/runtime/runtime.h
@@ -206,14 +206,6 @@ namespace internal {
F(ForInStep, 1, 1)
#define FOR_EACH_INTRINSIC_INTERPRETER(F) \
- F(InterpreterEquals, 2, 1) \
- F(InterpreterNotEquals, 2, 1) \
- F(InterpreterStrictEquals, 2, 1) \
- F(InterpreterStrictNotEquals, 2, 1) \
- F(InterpreterLessThan, 2, 1) \
- F(InterpreterGreaterThan, 2, 1) \
- F(InterpreterLessThanOrEqual, 2, 1) \
- F(InterpreterGreaterThanOrEqual, 2, 1) \
F(InterpreterToBoolean, 1, 1) \
F(InterpreterLogicalNot, 1, 1) \
F(InterpreterTypeOf, 1, 1) \
@@ -461,8 +453,6 @@ namespace internal {
F(ToLength, 1, 1) \
F(ToString, 1, 1) \
F(ToName, 1, 1) \
- F(Equals, 2, 1) \
- F(StrictEquals, 2, 1) \
F(SameValue, 2, 1) \
F(SameValueZero, 2, 1) \
F(Compare, 3, 1) \
@@ -497,7 +487,15 @@ namespace internal {
F(ShiftRightLogical, 2, 1) \
F(BitwiseAnd, 2, 1) \
F(BitwiseOr, 2, 1) \
- F(BitwiseXor, 2, 1)
+ F(BitwiseXor, 2, 1) \
+ F(Equal, 2, 1) \
+ F(NotEqual, 2, 1) \
+ F(StrictEqual, 2, 1) \
+ F(StrictNotEqual, 2, 1) \
+ F(LessThan, 2, 1) \
+ F(GreaterThan, 2, 1) \
+ F(LessThanOrEqual, 2, 1) \
+ F(GreaterThanOrEqual, 2, 1)
#define FOR_EACH_INTRINSIC_PROXY(F) \
F(IsJSProxy, 1, 1) \
diff --git a/deps/v8/src/type-feedback-vector.cc b/deps/v8/src/type-feedback-vector.cc
index 9e60fcffa7..4519bd65c2 100644
--- a/deps/v8/src/type-feedback-vector.cc
+++ b/deps/v8/src/type-feedback-vector.cc
@@ -340,6 +340,10 @@ void FeedbackNexus::ConfigurePremonomorphic() {
void FeedbackNexus::ConfigureMegamorphic() {
+ // Keyed ICs must use ConfigureMegamorphicKeyed.
+ DCHECK_NE(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector()->GetKind(slot()));
+ DCHECK_NE(FeedbackVectorSlotKind::KEYED_STORE_IC, vector()->GetKind(slot()));
+
Isolate* isolate = GetIsolate();
SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),
SKIP_WRITE_BARRIER);
@@ -347,6 +351,21 @@ void FeedbackNexus::ConfigureMegamorphic() {
SKIP_WRITE_BARRIER);
}
+void KeyedLoadICNexus::ConfigureMegamorphicKeyed(IcCheckType property_type) {
+ Isolate* isolate = GetIsolate();
+ SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),
+ SKIP_WRITE_BARRIER);
+ SetFeedbackExtra(Smi::FromInt(static_cast<int>(property_type)),
+ SKIP_WRITE_BARRIER);
+}
+
+void KeyedStoreICNexus::ConfigureMegamorphicKeyed(IcCheckType property_type) {
+ Isolate* isolate = GetIsolate();
+ SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),
+ SKIP_WRITE_BARRIER);
+ SetFeedbackExtra(Smi::FromInt(static_cast<int>(property_type)),
+ SKIP_WRITE_BARRIER);
+}
InlineCacheState LoadICNexus::StateFromFeedback() const {
Isolate* isolate = GetIsolate();
@@ -824,10 +843,20 @@ KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
return mode;
}
+IcCheckType KeyedLoadICNexus::GetKeyType() const {
+ Object* feedback = GetFeedback();
+ if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) {
+ return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value());
+ }
+ return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
+}
IcCheckType KeyedStoreICNexus::GetKeyType() const {
- // The structure of the vector slots tells us the type.
- return GetFeedback()->IsName() ? PROPERTY : ELEMENT;
+ Object* feedback = GetFeedback();
+ if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) {
+ return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value());
+ }
+ return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
}
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/type-feedback-vector.h b/deps/v8/src/type-feedback-vector.h
index d1c31a285f..effbfe7cc6 100644
--- a/deps/v8/src/type-feedback-vector.h
+++ b/deps/v8/src/type-feedback-vector.h
@@ -475,6 +475,9 @@ class KeyedLoadICNexus : public FeedbackNexus {
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers);
+ void ConfigureMegamorphicKeyed(IcCheckType property_type);
+
+ IcCheckType GetKeyType() const;
InlineCacheState StateFromFeedback() const override;
Name* FindFirstName() const override;
};
@@ -531,6 +534,7 @@ class KeyedStoreICNexus : public FeedbackNexus {
void ConfigurePolymorphic(MapHandleList* maps,
MapHandleList* transitioned_maps,
CodeHandleList* handlers);
+ void ConfigureMegamorphicKeyed(IcCheckType property_type);
KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
IcCheckType GetKeyType() const;
diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc
index eca5eccda4..ad253420bc 100644
--- a/deps/v8/src/type-info.cc
+++ b/deps/v8/src/type-info.cc
@@ -301,7 +301,7 @@ void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
KeyedLoadICNexus nexus(feedback_vector_, slot);
CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types);
*is_string = HasOnlyStringMaps(receiver_types);
- *key_type = nexus.FindFirstName() != NULL ? PROPERTY : ELEMENT;
+ *key_type = nexus.GetKeyType();
}
}
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc
index 4b3d02841b..f314b9cfcb 100644
--- a/deps/v8/src/x64/code-stubs-x64.cc
+++ b/deps/v8/src/x64/code-stubs-x64.cc
@@ -667,35 +667,34 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ movp(rdi, args.GetArgumentOperand(SUBJECT_STRING_ARGUMENT_INDEX));
__ JumpIfSmi(rdi, &runtime);
__ movp(r15, rdi); // Make a copy of the original subject string.
- __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
- __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
// rax: RegExp data (FixedArray)
// rdi: subject string
// r15: subject string
// Handle subject string according to its encoding and representation:
// (1) Sequential two byte? If yes, go to (9).
- // (2) Sequential one byte? If yes, go to (6).
- // (3) Anything but sequential or cons? If yes, go to (7).
- // (4) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (5a) Is subject sequential two byte? If yes, go to (9).
- // (5b) Is subject external? If yes, go to (8).
- // (6) One byte sequential. Load regexp code for one byte.
+ // (2) Sequential one byte? If yes, go to (5).
+ // (3) Sequential or cons? If not, go to (6).
+ // (4) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (5) One byte sequential. Load regexp code for one byte.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (7) Not a long external string? If yes, go to (10).
- // (8) External string. Make it, offset-wise, look like a sequential string.
- // (8a) Is the external string one byte? If yes, go to (6).
- // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
+ // (6) Long external string? If not, go to (10).
+ // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (8) Is the external string one byte? If yes, go to (5).
+ // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
// (10) Short external string or not a string? If yes, bail out to runtime.
- // (11) Sliced string. Replace subject with parent. Go to (5a).
+ // (11) Sliced string. Replace subject with parent. Go to (1).
+
+ Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */,
+ external_string /* 7 */, check_underlying /* 1 */,
+ not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */;
- Label seq_one_byte_string /* 6 */, seq_two_byte_string /* 9 */,
- external_string /* 8 */, check_underlying /* 5a */,
- not_seq_nor_cons /* 7 */, check_code /* E */,
- not_long_external /* 10 */;
+ __ bind(&check_underlying);
+ __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
+ __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
// (1) Sequential two byte? If yes, go to (9).
__ andb(rbx, Immediate(kIsNotStringMask |
@@ -705,14 +704,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string); // Go to (9).
- // (2) Sequential one byte? If yes, go to (6).
+ // (2) Sequential one byte? If yes, go to (5).
// Any other sequential string must be one byte.
__ andb(rbx, Immediate(kIsNotStringMask |
kStringRepresentationMask |
kShortExternalStringMask));
- __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (6).
+ __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5).
- // (3) Anything but sequential or cons? If yes, go to (7).
+ // (3) Sequential or cons? If not, go to (6).
// We check whether the subject string is a cons, since sequential strings
// have already been covered.
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
@@ -720,7 +719,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
__ cmpp(rbx, Immediate(kExternalStringTag));
- __ j(greater_equal, &not_seq_nor_cons); // Go to (7).
+ __ j(greater_equal, &not_seq_nor_cons); // Go to (6).
// (4) Cons string. Check that it's flat.
// Replace subject with first string and reload instance type.
@@ -728,22 +727,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
Heap::kempty_stringRootIndex);
__ j(not_equal, &runtime);
__ movp(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
- __ bind(&check_underlying);
- __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
- __ movp(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
+ __ jmp(&check_underlying);
- // (5a) Is subject sequential two byte? If yes, go to (9).
- __ testb(rbx, Immediate(kStringRepresentationMask | kStringEncodingMask));
- STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
- __ j(zero, &seq_two_byte_string); // Go to (9).
- // (5b) Is subject external? If yes, go to (8).
- __ testb(rbx, Immediate(kStringRepresentationMask));
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ j(not_zero, &external_string); // Go to (8)
-
- // (6) One byte sequential. Load regexp code for one byte.
+ // (5) One byte sequential. Load regexp code for one byte.
__ bind(&seq_one_byte_string);
// rax: RegExp data (FixedArray)
__ movp(r11, FieldOperand(rax, JSRegExp::kDataOneByteCodeOffset));
@@ -990,12 +976,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (7) Not a long external string? If yes, go to (10).
+ // (6) Long external string? If not, go to (10).
__ bind(&not_seq_nor_cons);
// Compare flags are still set from (3).
__ j(greater, &not_long_external, Label::kNear); // Go to (10).
- // (8) External string. Short external strings have been ruled out.
+ // (7) External string. Short external strings have been ruled out.
__ bind(&external_string);
__ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
__ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
@@ -1010,13 +996,13 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ subp(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
STATIC_ASSERT(kTwoByteStringTag == 0);
- // (8a) Is the external string one byte? If yes, go to (6).
+ // (8) Is the external string one byte? If yes, go to (5).
__ testb(rbx, Immediate(kStringEncodingMask));
- __ j(not_zero, &seq_one_byte_string); // Goto (6).
+ __ j(not_zero, &seq_one_byte_string); // Go to (5).
// rdi: subject string (flat two-byte)
// rax: RegExp data (FixedArray)
- // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
+ // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
__ bind(&seq_two_byte_string);
__ movp(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset));
__ Set(rcx, 0); // Type is two byte.
@@ -1029,7 +1015,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask));
__ j(not_zero, &runtime);
- // (11) Sliced string. Replace subject with parent. Go to (5a).
+ // (11) Sliced string. Replace subject with parent. Go to (1).
// Load offset into r14 and replace subject string with parent.
__ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
__ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
@@ -1320,16 +1306,23 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
}
__ bind(&runtime_call);
- // Push arguments below the return address to prepare jump to builtin.
- __ PopReturnAddressTo(rcx);
- __ Push(rdx);
- __ Push(rax);
-
- // Figure out which native to call and setup the arguments.
if (cc == equal) {
- __ PushReturnAddressFrom(rcx);
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(rdx);
+ __ Push(rax);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ LoadRoot(rdx, Heap::kTrueValueRootIndex);
+ __ subp(rax, rdx);
+ __ Ret();
} else {
+ // Push arguments below the return address to prepare jump to builtin.
+ __ PopReturnAddressTo(rcx);
+ __ Push(rdx);
+ __ Push(rax);
__ Push(Smi::FromInt(NegativeComparisonResult(cc)));
__ PushReturnAddressFrom(rcx);
__ TailCallRuntime(Runtime::kCompare);
diff --git a/deps/v8/src/x87/code-stubs-x87.cc b/deps/v8/src/x87/code-stubs-x87.cc
index e1ad6a7f5a..ff6c8d29e5 100644
--- a/deps/v8/src/x87/code-stubs-x87.cc
+++ b/deps/v8/src/x87/code-stubs-x87.cc
@@ -500,39 +500,37 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ mov(eax, Operand(esp, kSubjectOffset));
__ JumpIfSmi(eax, &runtime);
__ mov(edx, eax); // Make a copy of the original subject string.
- __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
// eax: subject string
// edx: subject string
- // ebx: subject string instance type
// ecx: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
// (1) Sequential two byte? If yes, go to (9).
- // (2) Sequential one byte? If yes, go to (6).
- // (3) Anything but sequential or cons? If yes, go to (7).
- // (4) Cons string. If the string is flat, replace subject with first string.
- // Otherwise bailout.
- // (5a) Is subject sequential two byte? If yes, go to (9).
- // (5b) Is subject external? If yes, go to (8).
- // (6) One byte sequential. Load regexp code for one byte.
+ // (2) Sequential one byte? If yes, go to (5).
+ // (3) Sequential or cons? If not, go to (6).
+ // (4) Cons string. If the string is flat, replace subject with first string
+ // and go to (1). Otherwise bail out to runtime.
+ // (5) One byte sequential. Load regexp code for one byte.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
- // (7) Not a long external string? If yes, go to (10).
- // (8) External string. Make it, offset-wise, look like a sequential string.
- // (8a) Is the external string one byte? If yes, go to (6).
- // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
+ // (6) Long external string? If not, go to (10).
+ // (7) External string. Make it, offset-wise, look like a sequential string.
+ // (8) Is the external string one byte? If yes, go to (5).
+ // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
// (10) Short external string or not a string? If yes, bail out to runtime.
- // (11) Sliced string. Replace subject with parent. Go to (5a).
+ // (11) Sliced string. Replace subject with parent. Go to (1).
- Label seq_one_byte_string /* 6 */, seq_two_byte_string /* 9 */,
- external_string /* 8 */, check_underlying /* 5a */,
- not_seq_nor_cons /* 7 */, check_code /* E */,
- not_long_external /* 10 */;
+ Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */,
+ external_string /* 7 */, check_underlying /* 1 */,
+ not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */;
+ __ bind(&check_underlying);
// (1) Sequential two byte? If yes, go to (9).
+ __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+
__ and_(ebx, kIsNotStringMask |
kStringRepresentationMask |
kStringEncodingMask |
@@ -540,14 +538,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
__ j(zero, &seq_two_byte_string); // Go to (9).
- // (2) Sequential one byte? If yes, go to (6).
+ // (2) Sequential one byte? If yes, go to (5).
// Any other sequential string must be one byte.
__ and_(ebx, Immediate(kIsNotStringMask |
kStringRepresentationMask |
kShortExternalStringMask));
- __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (6).
+ __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5).
- // (3) Anything but sequential or cons? If yes, go to (7).
+ // (3) Sequential or cons? If not, go to (6).
// We check whether the subject string is a cons, since sequential strings
// have already been covered.
STATIC_ASSERT(kConsStringTag < kExternalStringTag);
@@ -555,32 +553,19 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
__ cmp(ebx, Immediate(kExternalStringTag));
- __ j(greater_equal, &not_seq_nor_cons); // Go to (7).
+ __ j(greater_equal, &not_seq_nor_cons); // Go to (6).
// (4) Cons string. Check that it's flat.
// Replace subject with first string and reload instance type.
__ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string());
__ j(not_equal, &runtime);
__ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
- __ bind(&check_underlying);
- __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
- __ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
-
- // (5a) Is subject sequential two byte? If yes, go to (9).
- __ test_b(ebx, kStringRepresentationMask | kStringEncodingMask);
- STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
- __ j(zero, &seq_two_byte_string); // Go to (9).
- // (5b) Is subject external? If yes, go to (8).
- __ test_b(ebx, kStringRepresentationMask);
- // The underlying external string is never a short external string.
- STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
- STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
- __ j(not_zero, &external_string); // Go to (8).
+ __ jmp(&check_underlying);
// eax: sequential subject string (or look-alike, external string)
// edx: original subject string
// ecx: RegExp data (FixedArray)
- // (6) One byte sequential. Load regexp code for one byte.
+ // (5) One byte sequential. Load regexp code for one byte.
__ bind(&seq_one_byte_string);
// Load previous index and check range before edx is overwritten. We have
// to use edx instead of eax here because it might have been only made to
@@ -801,12 +786,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling.
- // (7) Not a long external string? If yes, go to (10).
+ // (6) Long external string? If not, go to (10).
__ bind(&not_seq_nor_cons);
// Compare flags are still set from (3).
__ j(greater, &not_long_external, Label::kNear); // Go to (10).
- // (8) External string. Short external strings have been ruled out.
+ // (7) External string. Short external strings have been ruled out.
__ bind(&external_string);
// Reload instance type.
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -822,14 +807,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
STATIC_ASSERT(kTwoByteStringTag == 0);
- // (8a) Is the external string one byte? If yes, go to (6).
+ // (8) Is the external string one byte? If yes, go to (5).
__ test_b(ebx, kStringEncodingMask);
- __ j(not_zero, &seq_one_byte_string); // Goto (6).
+ __ j(not_zero, &seq_one_byte_string); // Go to (5).
// eax: sequential subject string (or look-alike, external string)
// edx: original subject string
// ecx: RegExp data (FixedArray)
- // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
+ // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
__ bind(&seq_two_byte_string);
// Load previous index and check range before edx is overwritten. We have
// to use edx instead of eax here because it might have been only made to
@@ -849,11 +834,11 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag));
__ j(not_zero, &runtime);
- // (11) Sliced string. Replace subject with parent. Go to (5a).
+ // (11) Sliced string. Replace subject with parent. Go to (1).
// Load offset into edi and replace subject string with parent.
__ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset));
__ mov(eax, FieldOperand(eax, SlicedString::kParentOffset));
- __ jmp(&check_underlying); // Go to (5a).
+ __ jmp(&check_underlying); // Go to (1).
#endif // V8_INTERPRETED_REGEXP
}
@@ -1150,21 +1135,26 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
}
__ bind(&runtime_call);
- // Push arguments below the return address.
- __ pop(ecx);
- __ push(edx);
- __ push(eax);
-
- // Figure out which native to call and setup the arguments.
if (cc == equal) {
- __ push(ecx);
- __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(edx);
+ __ Push(eax);
+ __ CallRuntime(strict() ? Runtime::kStrictEqual : Runtime::kEqual);
+ }
+ // Turn true into 0 and false into some non-zero value.
+ STATIC_ASSERT(EQUAL == 0);
+ __ sub(eax, Immediate(isolate()->factory()->true_value()));
+ __ Ret();
} else {
+ // Push arguments below the return address.
+ __ pop(ecx);
+ __ push(edx);
+ __ push(eax);
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
// Restore return address on the stack.
__ push(ecx);
-
// Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
// tagged as a small integer.
__ TailCallRuntime(Runtime::kCompare);
diff --git a/deps/v8/src/zone.cc b/deps/v8/src/zone.cc
index 9dcebba2dc..1f722f2f60 100644
--- a/deps/v8/src/zone.cc
+++ b/deps/v8/src/zone.cc
@@ -105,7 +105,10 @@ void* Zone::New(size_t size) {
Address result = position_;
const size_t size_with_redzone = size + kASanRedzoneBytes;
- if (limit_ < position_ + size_with_redzone) {
+ const uintptr_t limit = reinterpret_cast<uintptr_t>(limit_);
+ const uintptr_t position = reinterpret_cast<uintptr_t>(position_);
+ // position_ > limit_ can be true after the alignment correction above.
+ if (limit < position || size_with_redzone > limit - position) {
result = NewExpand(size_with_redzone);
} else {
position_ += size_with_redzone;
@@ -222,7 +225,10 @@ Address Zone::NewExpand(size_t size) {
// Make sure the requested size is already properly aligned and that
// there isn't enough room in the Zone to satisfy the request.
DCHECK_EQ(size, RoundDown(size, kAlignment));
- DCHECK_LT(limit_, position_ + size);
+ DCHECK(limit_ < position_ ||
+ reinterpret_cast<uintptr_t>(limit_) -
+ reinterpret_cast<uintptr_t>(position_) <
+ size);
// Compute the new segment size. We use a 'high water mark'
// strategy, where we increase the segment size every time we expand
diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index 14ec12f21b..22321c3664 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/test/cctest/test-regexp.cc
@@ -1967,3 +1967,26 @@ TEST(UseCountRegExp) {
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultToStringError->IsObject());
}
+
+class UncachedExternalString
+ : public v8::String::ExternalOneByteStringResource {
+ public:
+ const char* data() const override { return "abcdefghijklmnopqrstuvwxyz"; }
+ size_t length() const override { return 26; }
+ bool IsCompressible() const override { return true; }
+};
+
+TEST(UncachedExternalString) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ v8::Local<v8::String> external =
+ v8::String::NewExternalOneByte(isolate, new UncachedExternalString())
+ .ToLocalChecked();
+ CHECK(v8::Utils::OpenHandle(*external)->map() ==
+ CcTest::i_isolate()->heap()->short_external_one_byte_string_map());
+ v8::Local<v8::Object> global = env->Global();
+ global->Set(env.local(), v8_str("external"), external).FromJust();
+ CompileRun("var re = /y(.)/; re.test('ab');");
+ ExpectString("external.substring(1).match(re)[1]", "z");
+}
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index 21d14c0a3e..b8e3f8e66f 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -862,7 +862,6 @@
'array-literal-feedback': [FAIL],
'undetectable-compare': [FAIL],
'debug-liveedit-2': [FAIL],
- 'compiler/deopt-tonumber-compare': [FAIL],
'es6/string-search': [FAIL],
'es6/mirror-collections': [FAIL],
'es6/regress/regress-468661': [FAIL],
diff --git a/deps/v8/test/mjsunit/regress/regress-4788-1.js b/deps/v8/test/mjsunit/regress/regress-4788-1.js
new file mode 100644
index 0000000000..347ab5e592
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4788-1.js
@@ -0,0 +1,25 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var f = (function() {
+ "use asm";
+ function foo(x) {
+ return x == 0;
+ }
+ return foo;
+})();
+
+function deopt(f) {
+ return {
+ toString : function() {
+ %DeoptimizeFunction(f);
+ return "2";
+ }
+ };
+}
+
+%OptimizeFunctionOnNextCall(f);
+assertFalse(f(deopt(f)));
diff --git a/deps/v8/test/mjsunit/regress/regress-4788-2.js b/deps/v8/test/mjsunit/regress/regress-4788-2.js
new file mode 100644
index 0000000000..5441705d54
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-4788-2.js
@@ -0,0 +1,25 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var f = (function() {
+ "use asm";
+ function foo(x) {
+ return x < x;
+ }
+ return foo;
+})();
+
+function deopt(f) {
+ return {
+ toString : function() {
+ %DeoptimizeFunction(f);
+ return "2";
+ }
+ };
+}
+
+%OptimizeFunctionOnNextCall(f);
+assertFalse(f(deopt(f)));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-594183.js b/deps/v8/test/mjsunit/regress/regress-crbug-594183.js
new file mode 100644
index 0000000000..c87e325458
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-594183.js
@@ -0,0 +1,82 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var global = {}
+
+var fish = [
+ {'name': 'foo'},
+ {'name': 'bar'},
+];
+
+for (var i = 0; i < fish.length; i++) {
+ global[fish[i].name] = 1;
+}
+
+function load() {
+ var sum = 0;
+ for (var i = 0; i < fish.length; i++) {
+ var name = fish[i].name;
+ sum += global[name];
+ }
+ return sum;
+}
+
+load();
+load();
+%OptimizeFunctionOnNextCall(load);
+load();
+assertOptimized(load);
+
+function store() {
+ for (var i = 0; i < fish.length; i++) {
+ var name = fish[i].name;
+ global[name] = 1;
+ }
+}
+
+store();
+store();
+%OptimizeFunctionOnNextCall(store);
+store();
+assertOptimized(store);
+
+// Regression test for KeyedStoreIC bug: would use PROPERTY mode erroneously.
+
+function store_element(obj, key) {
+ obj[key] = 0;
+}
+
+var o1 = new Array(3);
+var o2 = new Array(3);
+o2.o2 = "o2";
+var o3 = new Array(3);
+o3.o3 = "o3";
+var o4 = new Array(3);
+o4.o4 = "o4";
+var o5 = new Array(3);
+o5.o5 = "o5";
+// Make the KeyedStoreIC megamorphic.
+store_element(o1, 0); // Premonomorphic
+store_element(o1, 0); // Monomorphic
+store_element(o2, 0); // 2-way polymorphic.
+store_element(o3, 0); // 3-way polymorphic.
+store_element(o4, 0); // 4-way polymorphic.
+store_element(o5, 0); // Megamorphic.
+
+function inferrable_store(key) {
+ store_element(o5, key);
+}
+
+inferrable_store(0);
+inferrable_store(0);
+%OptimizeFunctionOnNextCall(inferrable_store);
+inferrable_store(0);
+assertOptimized(inferrable_store);
+// If |inferrable_store| emitted a generic keyed store, it won't deopt upon
+// seeing a property name key. It should have inferred a receiver map and
+// emitted an elements store, however.
+inferrable_store("deopt");
+assertUnoptimized(inferrable_store);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-605581.js b/deps/v8/test/mjsunit/regress/regress-crbug-605581.js
new file mode 100644
index 0000000000..0f1daabead
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-605581.js
@@ -0,0 +1,28 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+var Debug = debug.Debug;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ assertThrows(() => exec_state.frame(0).evaluate("bar.baz"), ReferenceError);
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+(function() {
+ debugger; // bar is still in TDZ at this point.
+ let bar = 1;
+ (x => bar); // force bar to be context-allocated.
+})();
+
+Debug.setListener(null);
+assertNull(exception);
diff --git a/deps/v8/test/mjsunit/regress/regress-v8-4972.js b/deps/v8/test/mjsunit/regress/regress-v8-4972.js
new file mode 100644
index 0000000000..689ae039ba
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-v8-4972.js
@@ -0,0 +1,5 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+new class extends new Proxy(class {},{}) {}
diff --git a/deps/v8/test/mjsunit/undetectable-compare.js b/deps/v8/test/mjsunit/undetectable-compare.js
index fbfbbe1051..3b97f5ee94 100644
--- a/deps/v8/test/mjsunit/undetectable-compare.js
+++ b/deps/v8/test/mjsunit/undetectable-compare.js
@@ -92,5 +92,4 @@ for (var i = 0; i < 5; i++) {
}
-assertFalse(undetectable == %GetUndetectable());
assertFalse(undetectable === %GetUndetectable());
diff --git a/deps/v8/test/unittests/runtime/runtime-interpreter-unittest.cc b/deps/v8/test/unittests/runtime/runtime-interpreter-unittest.cc
index 97b7992af9..c10ddcd319 100644
--- a/deps/v8/test/unittests/runtime/runtime-interpreter-unittest.cc
+++ b/deps/v8/test/unittests/runtime/runtime-interpreter-unittest.cc
@@ -23,12 +23,6 @@ class RuntimeInterpreterTest : public TestWithIsolateAndZone {
bool TestOperatorWithObjects(RuntimeMethod method, Handle<Object> lhs,
Handle<Object> rhs, bool expected);
- bool TestOperator(RuntimeMethod method, int32_t lhs, int32_t rhs,
- bool expected);
- bool TestOperator(RuntimeMethod method, double lhs, double rhs,
- bool expected);
- bool TestOperator(RuntimeMethod method, const char* lhs, const char* rhs,
- bool expected);
};
@@ -44,99 +38,6 @@ bool RuntimeInterpreterTest::TestOperatorWithObjects(RuntimeMethod method,
}
-bool RuntimeInterpreterTest::TestOperator(RuntimeMethod method, int32_t lhs,
- int32_t rhs, bool expected) {
- Handle<Object> x = isolate()->factory()->NewNumberFromInt(lhs);
- Handle<Object> y = isolate()->factory()->NewNumberFromInt(rhs);
- return TestOperatorWithObjects(method, x, y, expected);
-}
-
-
-bool RuntimeInterpreterTest::TestOperator(RuntimeMethod method, double lhs,
- double rhs, bool expected) {
- Handle<Object> x = isolate()->factory()->NewNumber(lhs);
- Handle<Object> y = isolate()->factory()->NewNumber(rhs);
- CHECK_EQ(HeapNumber::cast(*x)->value(), lhs);
- CHECK_EQ(HeapNumber::cast(*y)->value(), rhs);
- return TestOperatorWithObjects(method, x, y, expected);
-}
-
-
-bool RuntimeInterpreterTest::TestOperator(RuntimeMethod method, const char* lhs,
- const char* rhs, bool expected) {
- Handle<Object> x = isolate()->factory()->NewStringFromAsciiChecked(lhs);
- Handle<Object> y = isolate()->factory()->NewStringFromAsciiChecked(rhs);
- return TestOperatorWithObjects(method, x, y, expected);
-}
-
-
-TEST_F(RuntimeInterpreterTest, TestOperatorsWithIntegers) {
- int32_t inputs[] = {kMinInt, Smi::kMinValue, -17, -1, 0, 1,
- 991, Smi::kMaxValue, kMaxInt};
- TRACED_FOREACH(int, lhs, inputs) {
- TRACED_FOREACH(int, rhs, inputs) {
-#define INTEGER_OPERATOR_CHECK(r, op, x, y) \
- CHECK(TestOperator(Runtime_Interpreter##r, x, y, x op y))
- INTEGER_OPERATOR_CHECK(Equals, ==, lhs, rhs);
- INTEGER_OPERATOR_CHECK(NotEquals, !=, lhs, rhs);
- INTEGER_OPERATOR_CHECK(StrictEquals, ==, lhs, rhs);
- INTEGER_OPERATOR_CHECK(StrictNotEquals, !=, lhs, rhs);
- INTEGER_OPERATOR_CHECK(LessThan, <, lhs, rhs);
- INTEGER_OPERATOR_CHECK(GreaterThan, >, lhs, rhs);
- INTEGER_OPERATOR_CHECK(LessThanOrEqual, <=, lhs, rhs);
- INTEGER_OPERATOR_CHECK(GreaterThanOrEqual, >=, lhs, rhs);
-#undef INTEGER_OPERATOR_CHECK
- }
- }
-}
-
-
-TEST_F(RuntimeInterpreterTest, TestOperatorsWithDoubles) {
- double inputs[] = {std::numeric_limits<double>::min(),
- std::numeric_limits<double>::max(),
- -0.001,
- 0.01,
- 3.14,
- -6.02214086e23};
- TRACED_FOREACH(double, lhs, inputs) {
- TRACED_FOREACH(double, rhs, inputs) {
-#define DOUBLE_OPERATOR_CHECK(r, op, x, y) \
- CHECK(TestOperator(Runtime_Interpreter##r, x, y, x op y))
- DOUBLE_OPERATOR_CHECK(Equals, ==, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(NotEquals, !=, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(StrictEquals, ==, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(StrictNotEquals, !=, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(LessThan, <, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(GreaterThan, >, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(LessThanOrEqual, <=, lhs, rhs);
- DOUBLE_OPERATOR_CHECK(GreaterThanOrEqual, >=, lhs, rhs);
-#undef DOUBLE_OPERATOR_CHECK
- }
- }
-}
-
-
-TEST_F(RuntimeInterpreterTest, TestOperatorsWithString) {
- const char* inputs[] = {"abc", "a", "def", "0"};
- TRACED_FOREACH(const char*, lhs, inputs) {
- TRACED_FOREACH(const char*, rhs, inputs) {
-#define STRING_OPERATOR_CHECK(r, op, x, y) \
- CHECK(TestOperator(Runtime_Interpreter##r, x, y, \
- std::string(x) op std::string(y)))
- STRING_OPERATOR_CHECK(Equals, ==, lhs, rhs);
- STRING_OPERATOR_CHECK(NotEquals, !=, lhs, rhs);
- STRING_OPERATOR_CHECK(StrictEquals, ==, lhs, rhs);
- STRING_OPERATOR_CHECK(StrictNotEquals, !=, lhs, rhs);
- STRING_OPERATOR_CHECK(LessThan, <, lhs, rhs);
- STRING_OPERATOR_CHECK(GreaterThan, >, lhs, rhs);
- STRING_OPERATOR_CHECK(LessThanOrEqual, <=, lhs, rhs);
- STRING_OPERATOR_CHECK(GreaterThanOrEqual, >=, lhs, rhs);
-#undef STRING_OPERATOR_CHECK
- }
- }
-}
-
-
TEST_F(RuntimeInterpreterTest, ToBoolean) {
double quiet_nan = std::numeric_limits<double>::quiet_NaN();
std::pair<Handle<Object>, bool> cases[] = {
diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py
index 15eafedfce..d808a2f2d6 100644
--- a/deps/v8/tools/gen-postmortem-metadata.py
+++ b/deps/v8/tools/gen-postmortem-metadata.py
@@ -92,6 +92,8 @@ consts_misc = [
'value': 'DescriptorArray::kFirstIndex' },
{ 'name': 'prop_type_field',
'value': 'DATA' },
+ { 'name': 'prop_type_const_field',
+ 'value': 'DATA_CONSTANT' },
{ 'name': 'prop_type_mask',
'value': 'PropertyDetails::TypeField::kMask' },
{ 'name': 'prop_index_mask',