From: jarin@chromium.org Date: Mon, 31 Mar 2014 11:58:53 +0000 (+0000) Subject: Add missing lazy deopt point for the TransitionElementsKind instruction. X-Git-Tag: upstream/4.7.83~9935 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d65fe51ca0744138a83bad067a9eb58b3a96c8d0;p=platform%2Fupstream%2Fv8.git Add missing lazy deopt point for the TransitionElementsKind instruction. R=mvstanton@chromium.org, yangguo@chromium.org BUG=357105 TEST=test/mjsunit/regress/regress-357105.js LOG=N Review URL: https://codereview.chromium.org/216963002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20347 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 55705b8..c280999 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); } } diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 7152ba2..9cf94ee 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); } diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 60bf51e..6dccc5f 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); } } diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h index da3c5f1..fcb1552 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; diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index cd931e9..abae911 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 from_map = instr->original_map(); Handle 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); } diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 0dbe3da..b3c06d6 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); } diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 696c6be..8fa6dbd 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); } } diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 970a1bf..e6f52d8 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); } diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 752f676..1ff8915 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); } } diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index cc9b21b..849e2d4 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); } diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 8c4f24e..0dba33d 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); } } diff --git a/test/mjsunit/regress/regress-357105.js b/test/mjsunit/regress/regress-357105.js new file mode 100644 index 0000000..d3eefd0 --- /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);