Reviewers: Yang,
Description:
Add missing lazy deopt point for the TransitionElementsKind instruction.
[email protected]
BUG=357105
TEST=test/mjsunit/regress/regress-357105.js
LOG=N
Please review this at https://codereview.chromium.org/216963002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+58, -30 lines):
M src/arm/lithium-arm.cc
M src/arm/lithium-codegen-arm.cc
M src/arm64/lithium-arm64.h
M src/arm64/lithium-arm64.cc
M src/arm64/lithium-codegen-arm64.cc
M src/ia32/lithium-codegen-ia32.cc
M src/ia32/lithium-ia32.cc
M src/mips/lithium-codegen-mips.cc
M src/mips/lithium-mips.cc
M src/x64/lithium-codegen-x64.cc
M src/x64/lithium-x64.cc
A test/mjsunit/regress/regress-357105.js
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
55705b8073cfd0a8e3f91b8d7aa1beca58b1b978..c280999ca2b0849d7710fa89814d9ae472de7aa4
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -2225,17 +2225,18 @@ LInstruction*
LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), r0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
7152ba21cc2af690406d1d209eba6087c6f53dce..9cf94eea8470384be29a04335fef80dceb0ba50e
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4381,15 +4381,15 @@ void
LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
scratch, GetLinkRegisterState(), kDontSaveFPRegs);
} else {
ASSERT(ToRegister(instr->context()).is(cp));
+ ASSERT(object_reg.is(r0));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ Move(r0, object_reg);
__ Move(r1, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ bind(¬_applicable);
}
Index: src/arm64/lithium-arm64.cc
diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
index
60bf51ebbdc7d33170faff92dcf106d777a1f7c4..6dccc5ffaa86218b80176f94843d5d8c3cd63fc9
100644
--- a/src/arm64/lithium-arm64.cc
+++ b/src/arm64/lithium-arm64.cc
@@ -2365,17 +2365,18 @@ LInstruction*
LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL,
TempRegister(),
TempRegister());
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), x0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
- new(zone()) LTransitionElementsKind(object, context,
TempRegister());
- return AssignPointerMap(result);
+ new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
+ return MarkAsCall(result, instr);
}
}
Index: src/arm64/lithium-arm64.h
diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h
index
da3c5f17b5a7ed757882b4843923e7afa817a97a..fcb15526048f0d273dd746ec2ae1a8756019824c
100644
--- a/src/arm64/lithium-arm64.h
+++ b/src/arm64/lithium-arm64.h
@@ -2778,7 +2778,7 @@ class LTransitionElementsKind V8_FINAL : public
LTemplateInstruction<0, 2, 2> {
LTransitionElementsKind(LOperand* object,
LOperand* context,
LOperand* temp1,
- LOperand* temp2 = NULL) {
+ LOperand* temp2) {
inputs_[0] = object;
inputs_[1] = context;
temps_[0] = temp1;
Index: src/arm64/lithium-codegen-arm64.cc
diff --git a/src/arm64/lithium-codegen-arm64.cc
b/src/arm64/lithium-codegen-arm64.cc
index
cd931e934c7c8b52fc5633d997b563368ea03828..abae911512cace247fdfd25a3f267048bc21e760
100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -5659,7 +5659,6 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr)
{
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object = ToRegister(instr->object());
- Register temp1 = ToRegister(instr->temp1());
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
@@ -5667,26 +5666,34 @@ void
LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
ElementsKind to_kind = instr->to_kind();
Label not_applicable;
- __ CheckMap(object, temp1, from_map, ¬_applicable, DONT_DO_SMI_CHECK);
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+ Register temp1 = ToRegister(instr->temp1());
Register new_map = ToRegister(instr->temp2());
+ __ CheckMap(object, temp1, from_map, ¬_applicable,
DONT_DO_SMI_CHECK);
__ Mov(new_map, Operand(to_map));
__ Str(new_map, FieldMemOperand(object, HeapObject::kMapOffset));
// Write barrier.
__ RecordWriteField(object, HeapObject::kMapOffset, new_map, temp1,
GetLinkRegisterState(), kDontSaveFPRegs);
} else {
+ {
+ UseScratchRegisterScope temps(masm());
+ // Use the temp register only in a restricted scope - the codegen
checks
+ // that we do not use any register across a call.
+ __ CheckMap(object, temps.AcquireX(), from_map, ¬_applicable,
+ DONT_DO_SMI_CHECK);
+ }
+ ASSERT(object.is(x0));
ASSERT(ToRegister(instr->context()).is(cp));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ Mov(x0, object);
__ Mov(x1, Operand(to_map));
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ Bind(¬_applicable);
}
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
0dbe3da13d3f1b4f59bfd2b1f31a1fbaf84c6eaa..b3c06d6778957c9152a6fe2bfa42737faeb5f419
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4736,16 +4736,14 @@ void
LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
kDontSaveFPRegs);
} else {
ASSERT(ToRegister(instr->context()).is(esi));
+ ASSERT(object_reg.is(eax));
PushSafepointRegistersScope scope(this);
- if (!object_reg.is(eax)) {
- __ mov(eax, object_reg);
- }
__ mov(ebx, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ RecordSafepointWithLazyDeopt(instr,
+ RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
}
__ bind(¬_applicable);
}
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index
696c6be6e8159cd8ba3427dab2f8eb6e0717400c..8fa6dbdcaed689256948f7c21e6a4785100c082d
100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -2345,7 +2345,6 @@ LInstruction*
LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
@@ -2355,10 +2354,11 @@ LInstruction*
LChunkBuilder::DoTransitionElementsKind(
new_map_reg, temp_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), eax);
LOperand* context = UseFixed(instr->context(), esi);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
Index: src/mips/lithium-codegen-mips.cc
diff --git a/src/mips/lithium-codegen-mips.cc
b/src/mips/lithium-codegen-mips.cc
index
970a1bfc25c197ad78e95442408aa05a59cebd15..e6f52d84b707ef82d3385eddea892525039b744d
100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -4401,16 +4401,16 @@ void
LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
scratch, GetRAState(), kDontSaveFPRegs);
} else {
+ ASSERT(object_reg.is(a0));
ASSERT(ToRegister(instr->context()).is(cp));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ mov(a0, object_reg);
__ li(a1, Operand(to_map));
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ bind(¬_applicable);
}
Index: src/mips/lithium-mips.cc
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index
752f67673d76841120c4a2b4be96fbef29ec84cd..1ff8915f515bbe083112adf622ddf926b4c448f2
100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -2178,17 +2178,18 @@ LInstruction*
LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), a0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
cc9b21b79f671ff017326202cbdba499af56e80f..849e2d4ecaa6bf131dc13a938dba82b667e1dd81
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -4318,17 +4318,14 @@ void
LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
ToRegister(instr->temp()), kDontSaveFPRegs);
} else {
+ ASSERT(object_reg.is(rax));
ASSERT(ToRegister(instr->context()).is(rsi));
PushSafepointRegistersScope scope(this);
- if (!object_reg.is(rax)) {
- __ movp(rax, object_reg);
- }
__ Move(rbx, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS,
0);
}
__ bind(¬_applicable);
}
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index
8c4f24e8fb465680beaf3d0a1bd1deb102cb676f..0dba33dc91ea83959c8859ebe3d3a3b5a09adae8
100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2243,7 +2243,6 @@ LInstruction*
LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
@@ -2252,10 +2251,11 @@ LInstruction*
LChunkBuilder::DoTransitionElementsKind(
object, NULL, new_map_reg, temp_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), rax);
LOperand* context = UseFixed(instr->context(), rsi);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
Index: test/mjsunit/regress/regress-357105.js
diff --git a/test/mjsunit/regress/regress-357105.js
b/test/mjsunit/regress/regress-357105.js
new file mode 100644
index
0000000000000000000000000000000000000000..d3eefd0f1b6a4616e5b57a2e79555619d76993bf
--- /dev/null
+++ b/test/mjsunit/regress/regress-357105.js
@@ -0,0 +1,23 @@
+// Copyright 2014 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 --expose-gc
+
+var global = { };
+
+function do_nothing() { }
+
+function f(opt_gc) {
+ var x = new Array(3);
+ x[0] = 10;
+ opt_gc();
+ global[1] = 15.5;
+ return x;
+}
+
+gc();
+global = f(gc);
+global = f(do_nothing);
+%OptimizeFunctionOnNextCall(f);
+global = f(do_nothing);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.