 Chromium Code Reviews
 Chromium Code Reviews Issue 6793017:
  In LCodeGen::DoDeferredLInstanceOfKnownGlobal emit safepoint with registers for the call to stub.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 6793017:
  In LCodeGen::DoDeferredLInstanceOfKnownGlobal emit safepoint with registers for the call to stub.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| Index: src/ia32/lithium-codegen-ia32.cc | 
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc | 
| index eb31d5aeeb339890dc7eb03f6f7b1f822d703720..559e4db4a588b1ffb4fcb4bad43df01ad1e44a29 100644 | 
| --- a/src/ia32/lithium-codegen-ia32.cc | 
| +++ b/src/ia32/lithium-codegen-ia32.cc | 
| @@ -408,20 +408,21 @@ void LCodeGen::AddToTranslation(Translation* translation, | 
| } | 
| -void LCodeGen::CallCode(Handle<Code> code, | 
| - RelocInfo::Mode mode, | 
| - LInstruction* instr, | 
| - bool adjusted) { | 
| +void LCodeGen::CallCodeGeneric(Handle<Code> code, | 
| + RelocInfo::Mode mode, | 
| + LInstruction* instr, | 
| + ContextMode context_mode, | 
| + SafepointMode safepoint_mode) { | 
| ASSERT(instr != NULL); | 
| LPointerMap* pointers = instr->pointer_map(); | 
| RecordPosition(pointers->position()); | 
| - if (!adjusted) { | 
| + if (context_mode == RESTORE_CONTEXT) { | 
| __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| } | 
| __ call(code, mode); | 
| - RegisterLazyDeoptimization(instr); | 
| + RegisterLazyDeoptimization(instr, safepoint_mode); | 
| // Signal that we don't inline smi code before these stubs in the | 
| // optimizing code generator. | 
| @@ -432,25 +433,44 @@ void LCodeGen::CallCode(Handle<Code> code, | 
| } | 
| +void LCodeGen::CallCode(Handle<Code> code, | 
| + RelocInfo::Mode mode, | 
| + LInstruction* instr, | 
| + ContextMode context_mode) { | 
| + CallCodeGeneric(code, mode, instr, context_mode, RECORD_SIMPLE_SAFEPOINT); | 
| +} | 
| + | 
| + | 
| void LCodeGen::CallRuntime(const Runtime::Function* fun, | 
| int argc, | 
| LInstruction* instr, | 
| - bool adjusted) { | 
| + ContextMode context_mode) { | 
| ASSERT(instr != NULL); | 
| ASSERT(instr->HasPointerMap()); | 
| LPointerMap* pointers = instr->pointer_map(); | 
| RecordPosition(pointers->position()); | 
| - if (!adjusted) { | 
| + if (context_mode == RESTORE_CONTEXT) { | 
| __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| } | 
| __ CallRuntime(fun, argc); | 
| - RegisterLazyDeoptimization(instr); | 
| + RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 
| +} | 
| + | 
| + | 
| +void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, | 
| + int argc, | 
| + LInstruction* instr) { | 
| + __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| + __ CallRuntimeSaveDoubles(id); | 
| + RecordSafepointWithRegisters( | 
| + instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); | 
| } | 
| -void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) { | 
| +void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr, | 
| + SafepointMode safepoint_mode) { | 
| // Create the environment to bailout to. If the call has side effects | 
| // execution has to continue after the call otherwise execution can continue | 
| // from a previous bailout point repeating the call. | 
| @@ -462,8 +482,16 @@ void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) { | 
| } | 
| RegisterEnvironmentForDeoptimization(deoptimization_environment); | 
| - RecordSafepoint(instr->pointer_map(), | 
| - deoptimization_environment->deoptimization_index()); | 
| + if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { | 
| + RecordSafepoint(instr->pointer_map(), | 
| + deoptimization_environment->deoptimization_index()); | 
| + } else { | 
| + ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 
| + RecordSafepointWithRegisters( | 
| + instr->pointer_map(), | 
| + 0, | 
| + deoptimization_environment->deoptimization_index()); | 
| + } | 
| } | 
| @@ -612,6 +640,7 @@ void LCodeGen::RecordSafepoint( | 
| Safepoint::Kind kind, | 
| int arguments, | 
| int deoptimization_index) { | 
| + ASSERT(kind == Safepoint::kWithRegisters || !safepoint_registers_pushed_); | 
| 
fschneider
2011/04/04 14:56:34
You could assert stronger:
ASSERT((kind == Safepo
 | 
| const ZoneList<LOperand*>* operands = pointers->operands(); | 
| Safepoint safepoint = safepoints_.DefineSafepoint(masm(), | 
| kind, arguments, deoptimization_index); | 
| @@ -697,38 +726,38 @@ void LCodeGen::DoCallStub(LCallStub* instr) { | 
| switch (instr->hydrogen()->major_key()) { | 
| case CodeStub::RegExpConstructResult: { | 
| RegExpConstructResultStub stub; | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| case CodeStub::RegExpExec: { | 
| RegExpExecStub stub; | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| case CodeStub::SubString: { | 
| SubStringStub stub; | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| case CodeStub::NumberToString: { | 
| NumberToStringStub stub; | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| case CodeStub::StringAdd: { | 
| StringAddStub stub(NO_STRING_ADD_FLAGS); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| case CodeStub::StringCompare: { | 
| StringCompareStub stub; | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| case CodeStub::TranscendentalCache: { | 
| TranscendentalCacheStub stub(instr->transcendental_type(), | 
| TranscendentalCacheStub::TAGGED); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| break; | 
| } | 
| default: | 
| @@ -1143,7 +1172,7 @@ void LCodeGen::DoBitNotI(LBitNotI* instr) { | 
| void LCodeGen::DoThrow(LThrow* instr) { | 
| __ push(ToOperand(instr->InputAt(0))); | 
| - CallRuntime(Runtime::kThrow, 1, instr, false); | 
| + CallRuntime(Runtime::kThrow, 1, instr, RESTORE_CONTEXT); | 
| if (FLAG_debug_code) { | 
| Comment("Unreachable code."); | 
| @@ -1218,7 +1247,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 
| ASSERT(ToRegister(instr->result()).is(eax)); | 
| TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } | 
| @@ -1330,12 +1359,8 @@ void LCodeGen::EmitGoto(int block, LDeferredCode* deferred_stack_check) { | 
| void LCodeGen::DoDeferredStackCheck(LGoto* instr) { | 
| - __ pushad(); | 
| - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| - __ CallRuntimeSaveDoubles(Runtime::kStackGuard); | 
| - RecordSafepointWithRegisters( | 
| - instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 
| - __ popad(); | 
| + PushSafepointRegistersScope scope(this); | 
| + CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr); | 
| } | 
| void LCodeGen::DoGoto(LGoto* instr) { | 
| @@ -1837,7 +1862,7 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 
| // Object and function are in fixed registers defined by the stub. | 
| ASSERT(ToRegister(instr->context()).is(esi)); | 
| InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| NearLabel true_value, done; | 
| __ test(eax, Operand(eax)); | 
| @@ -1856,7 +1881,7 @@ void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { | 
| int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| __ test(eax, Operand(eax)); | 
| EmitBranch(true_block, false_block, zero); | 
| } | 
| @@ -1928,7 +1953,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 
| void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | 
| Label* map_check) { | 
| - __ PushSafepointRegisters(); | 
| + PushSafepointRegistersScope scope(this); | 
| InstanceofStub::Flags flags = InstanceofStub::kNoFlags; | 
| flags = static_cast<InstanceofStub::Flags>( | 
| @@ -1949,10 +1974,13 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | 
| int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; | 
| __ mov(temp, Immediate(delta)); | 
| __ StoreToSafepointRegisterSlot(temp, temp); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCodeGeneric(stub.GetCode(), | 
| + RelocInfo::CODE_TARGET, | 
| + instr, | 
| + RESTORE_CONTEXT, | 
| + RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 
| // Put the result value into the eax slot and restore all registers. | 
| __ StoreToSafepointRegisterSlot(eax, eax); | 
| - __ PopSafepointRegisters(); | 
| } | 
| @@ -1980,7 +2008,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) { | 
| Token::Value op = instr->op(); | 
| Handle<Code> ic = CompareIC::GetUninitialized(op); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| Condition condition = ComputeCompareCondition(op); | 
| if (op == Token::GT || op == Token::LTE) { | 
| @@ -2003,7 +2031,7 @@ void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) { | 
| int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| Handle<Code> ic = CompareIC::GetUninitialized(op); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| // The compare stub expects compare condition and the input operands | 
| // reversed for GT and LTE. | 
| @@ -2051,7 +2079,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 
| RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : | 
| RelocInfo::CODE_TARGET_CONTEXT; | 
| Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
| - CallCode(ic, mode, instr); | 
| + CallCode(ic, mode, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -2135,7 +2163,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { | 
| ASSERT(instr->hydrogen()->need_generic()); | 
| __ mov(ecx, name); | 
| Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } else { | 
| NearLabel done; | 
| for (int i = 0; i < map_count - 1; ++i) { | 
| @@ -2157,7 +2185,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { | 
| __ bind(&generic); | 
| __ mov(ecx, name); | 
| Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } else { | 
| DeoptimizeIf(not_equal, instr->environment()); | 
| EmitLoadField(result, object, map, name); | 
| @@ -2174,7 +2202,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 
| __ mov(ecx, instr->name()); | 
| Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -2337,7 +2365,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 
| ASSERT(ToRegister(instr->key()).is(eax)); | 
| Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -2525,7 +2553,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 
| } | 
| // Setup deoptimization. | 
| - RegisterLazyDeoptimization(instr); | 
| + RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); | 
| } | 
| @@ -2547,7 +2575,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
| Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; | 
| // Preserve the value of all registers. | 
| - __ PushSafepointRegisters(); | 
| + PushSafepointRegistersScope scope(this); | 
| Label negative; | 
| __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 
| @@ -2568,10 +2596,8 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
| // Slow case: Call the runtime system to do the number allocation. | 
| __ bind(&slow); | 
| - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| - __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 
| - RecordSafepointWithRegisters( | 
| - instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 
| + CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 
| + | 
| // Set the pointer to the new heap number in tmp. | 
| if (!tmp.is(eax)) __ mov(tmp, eax); | 
| @@ -2587,7 +2613,6 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
| __ StoreToSafepointRegisterSlot(input_reg, tmp); | 
| __ bind(&done); | 
| - __ PopSafepointRegisters(); | 
| } | 
| @@ -2779,7 +2804,7 @@ void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 
| ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 
| TranscendentalCacheStub stub(TranscendentalCache::LOG, | 
| TranscendentalCacheStub::UNTAGGED); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } | 
| @@ -2787,7 +2812,7 @@ void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { | 
| ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 
| TranscendentalCacheStub stub(TranscendentalCache::COS, | 
| TranscendentalCacheStub::UNTAGGED); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } | 
| @@ -2795,7 +2820,7 @@ void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { | 
| ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 
| TranscendentalCacheStub stub(TranscendentalCache::SIN, | 
| TranscendentalCacheStub::UNTAGGED); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } | 
| @@ -2840,7 +2865,7 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 
| int arity = instr->arity(); | 
| Handle<Code> ic = isolate()->stub_cache()-> | 
| ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -2852,7 +2877,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { | 
| Handle<Code> ic = isolate()->stub_cache()-> | 
| ComputeCallInitialize(arity, NOT_IN_LOOP); | 
| __ mov(ecx, instr->name()); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -2862,7 +2887,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { | 
| int arity = instr->arity(); | 
| CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| __ Drop(1); | 
| } | 
| @@ -2875,7 +2900,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { | 
| Handle<Code> ic = isolate()->stub_cache()-> | 
| ComputeCallInitialize(arity, NOT_IN_LOOP); | 
| __ mov(ecx, instr->name()); | 
| - CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -2893,12 +2918,12 @@ void LCodeGen::DoCallNew(LCallNew* instr) { | 
| Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 
| __ Set(eax, Immediate(instr->arity())); | 
| - CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); | 
| + CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr, CONTEXT_ADJUSTED); | 
| } | 
| void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 
| - CallRuntime(instr->function(), instr->arity(), instr, false); | 
| + CallRuntime(instr->function(), instr->arity(), instr, RESTORE_CONTEXT); | 
| } | 
| @@ -2941,7 +2966,7 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 
| Handle<Code> ic = info_->is_strict() | 
| ? isolate()->builtins()->StoreIC_Initialize_Strict() | 
| : isolate()->builtins()->StoreIC_Initialize(); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -3041,7 +3066,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 
| Handle<Code> ic = info_->is_strict() | 
| ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 
| : isolate()->builtins()->KeyedStoreIC_Initialize(); | 
| - CallCode(ic, RelocInfo::CODE_TARGET, instr); | 
| + CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -3159,7 +3184,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { | 
| // contained in the register pointer map. | 
| __ Set(result, Immediate(0)); | 
| - __ PushSafepointRegisters(); | 
| + PushSafepointRegistersScope scope(this); | 
| __ push(string); | 
| // Push the index as a smi. This is safe because of the checks in | 
| // DoStringCharCodeAt above. | 
| @@ -3172,16 +3197,12 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { | 
| __ SmiTag(index); | 
| __ push(index); | 
| } | 
| - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| - __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt); | 
| - RecordSafepointWithRegisters( | 
| - instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex); | 
| + CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); | 
| if (FLAG_debug_code) { | 
| __ AbortIfNotSmi(eax); | 
| } | 
| __ SmiUntag(eax); | 
| __ StoreToSafepointRegisterSlot(result, eax); | 
| - __ PopSafepointRegisters(); | 
| } | 
| @@ -3224,14 +3245,11 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { | 
| // contained in the register pointer map. | 
| __ Set(result, Immediate(0)); | 
| - __ PushSafepointRegisters(); | 
| + PushSafepointRegistersScope scope(this); | 
| __ SmiTag(char_code); | 
| __ push(char_code); | 
| - __ CallRuntimeSaveDoubles(Runtime::kCharFromCode); | 
| - RecordSafepointWithRegisters( | 
| - instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex); | 
| + CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); | 
| __ StoreToSafepointRegisterSlot(result, eax); | 
| - __ PopSafepointRegisters(); | 
| } | 
| @@ -3278,7 +3296,7 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | 
| Register tmp = reg.is(eax) ? ecx : eax; | 
| // Preserve the value of all registers. | 
| - __ PushSafepointRegisters(); | 
| + PushSafepointRegistersScope scope(this); | 
| // There was overflow, so bits 30 and 31 of the original integer | 
| // disagree. Try to allocate a heap number in new space and store | 
| @@ -3300,10 +3318,7 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | 
| // integer value. | 
| __ StoreToSafepointRegisterSlot(reg, Immediate(0)); | 
| - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| - __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 
| - RecordSafepointWithRegisters( | 
| - instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 
| + CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 
| if (!reg.is(eax)) __ mov(reg, eax); | 
| // Done. Put the value in xmm0 into the value of the allocated heap | 
| @@ -3311,7 +3326,6 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | 
| __ bind(&done); | 
| __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); | 
| __ StoreToSafepointRegisterSlot(reg, reg); | 
| - __ PopSafepointRegisters(); | 
| } | 
| @@ -3347,13 +3361,9 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 
| Register reg = ToRegister(instr->result()); | 
| __ Set(reg, Immediate(0)); | 
| - __ PushSafepointRegisters(); | 
| - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| - __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 
| - RecordSafepointWithRegisters( | 
| - instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 
| + PushSafepointRegistersScope scope(this); | 
| + CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 
| __ StoreToSafepointRegisterSlot(reg, eax); | 
| - __ PopSafepointRegisters(); | 
| } | 
| @@ -3768,16 +3778,16 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 
| FastCloneShallowArrayStub::Mode mode = | 
| FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; | 
| FastCloneShallowArrayStub stub(mode, length); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } else if (instr->hydrogen()->depth() > 1) { | 
| - CallRuntime(Runtime::kCreateArrayLiteral, 3, instr, false); | 
| + CallRuntime(Runtime::kCreateArrayLiteral, 3, instr, RESTORE_CONTEXT); | 
| } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 
| - CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr, false); | 
| + CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr, RESTORE_CONTEXT); | 
| } else { | 
| FastCloneShallowArrayStub::Mode mode = | 
| FastCloneShallowArrayStub::CLONE_ELEMENTS; | 
| FastCloneShallowArrayStub stub(mode, length); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } | 
| } | 
| @@ -3799,9 +3809,12 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 
| // Pick the right runtime function to call. | 
| if (instr->hydrogen()->depth() > 1) { | 
| - CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); | 
| + CallRuntime(Runtime::kCreateObjectLiteral, 4, instr, CONTEXT_ADJUSTED); | 
| } else { | 
| - CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); | 
| + CallRuntime(Runtime::kCreateObjectLiteralShallow, | 
| + 4, | 
| + instr, | 
| + CONTEXT_ADJUSTED); | 
| } | 
| } | 
| @@ -3809,7 +3822,7 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 
| void LCodeGen::DoToFastProperties(LToFastProperties* instr) { | 
| ASSERT(ToRegister(instr->InputAt(0)).is(eax)); | 
| __ push(eax); | 
| - CallRuntime(Runtime::kToFastProperties, 1, instr); | 
| + CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED); | 
| } | 
| @@ -3834,7 +3847,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 
| __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 
| __ push(Immediate(instr->hydrogen()->pattern())); | 
| __ push(Immediate(instr->hydrogen()->flags())); | 
| - CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, false); | 
| + CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT); | 
| __ mov(ebx, eax); | 
| __ bind(&materialized); | 
| @@ -3846,7 +3859,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 
| __ bind(&runtime_allocate); | 
| __ push(ebx); | 
| __ push(Immediate(Smi::FromInt(size))); | 
| - CallRuntime(Runtime::kAllocateInNewSpace, 1, instr, false); | 
| + CallRuntime(Runtime::kAllocateInNewSpace, 1, instr, RESTORE_CONTEXT); | 
| __ pop(ebx); | 
| __ bind(&allocated); | 
| @@ -3874,14 +3887,14 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 
| FastNewClosureStub stub( | 
| shared_info->strict_mode() ? kStrictMode : kNonStrictMode); | 
| __ push(Immediate(shared_info)); | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| } else { | 
| __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| __ push(Immediate(shared_info)); | 
| __ push(Immediate(pretenure | 
| ? factory()->true_value() | 
| : factory()->false_value())); | 
| - CallRuntime(Runtime::kNewClosure, 3, instr, false); | 
| + CallRuntime(Runtime::kNewClosure, 3, instr, RESTORE_CONTEXT); | 
| } | 
| } | 
| @@ -3893,7 +3906,7 @@ void LCodeGen::DoTypeof(LTypeof* instr) { | 
| } else { | 
| __ push(ToOperand(input)); | 
| } | 
| - CallRuntime(Runtime::kTypeof, 1, instr, false); | 
| + CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); | 
| } | 
| @@ -4096,7 +4109,7 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { | 
| __ j(above_equal, &done); | 
| StackCheckStub stub; | 
| - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, false); | 
| + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| __ bind(&done); | 
| } |