Index: src/x87/code-stubs-x87.cc |
diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc |
index 35514c35607b6e9fd3462a5f16ac25afdc7df2fe..9f180744d6d88378b21efd3e3f82dee41a75d7e1 100644 |
--- a/src/x87/code-stubs-x87.cc |
+++ b/src/x87/code-stubs-x87.cc |
@@ -127,6 +127,11 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
// store the registers in any particular way, but we do have to store and |
// restore them. |
__ pushad(); |
+ if (save_doubles()) { |
+ // Save FPU stat in m108byte. |
+ __ sub(esp, Immediate(108)); |
+ __ fnsave(Operand(esp, 0)); |
+ } |
const int argument_count = 1; |
AllowExternalCallThatCantCauseGC scope(masm); |
@@ -136,6 +141,11 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
__ CallCFunction( |
ExternalReference::store_buffer_overflow_function(isolate()), |
argument_count); |
+ if (save_doubles()) { |
+ // Restore FPU stat in m108byte. |
+ __ frstor(Operand(esp, 0)); |
+ __ add(esp, Immediate(108)); |
+ } |
__ popad(); |
__ ret(0); |
} |
@@ -1118,13 +1128,15 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ RecordWriteField(ebx, |
RegExpImpl::kLastSubjectOffset, |
eax, |
- edi); |
+ edi, |
+ kDontSaveFPRegs); |
__ mov(eax, ecx); |
__ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax); |
__ RecordWriteField(ebx, |
RegExpImpl::kLastInputOffset, |
eax, |
- edi); |
+ edi, |
+ kDontSaveFPRegs); |
// Get the static offsets vector filled by the native regexp code. |
ExternalReference address_of_static_offsets_vector = |
@@ -1618,7 +1630,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { |
__ push(edi); |
__ push(ebx); |
__ push(edx); |
- __ RecordWriteArray(ebx, edi, edx, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
+ __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs, |
+ EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
__ pop(edx); |
__ pop(ebx); |
__ pop(edi); |
@@ -1989,12 +2002,19 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
void CodeStub::GenerateFPStubs(Isolate* isolate) { |
- // Do nothing. |
+ CEntryStub save_doubles(isolate, 1, kSaveFPRegs); |
+ // Stubs might already be in the snapshot, detect that and don't regenerate, |
+ // which would lead to code stub initialization state being messed up. |
+ Code* save_doubles_code; |
+ if (!save_doubles.FindCodeInCache(&save_doubles_code)) { |
+ save_doubles_code = *(save_doubles.GetCode()); |
+ } |
+ isolate->set_fp_stubs_generated(true); |
} |
void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
- CEntryStub stub(isolate, 1); |
+ CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
stub.GetCode(); |
} |
@@ -2010,7 +2030,7 @@ void CEntryStub::Generate(MacroAssembler* masm) { |
ProfileEntryHookStub::MaybeCallEntryHook(masm); |
// Enter the exit frame that transitions from JavaScript to C++. |
- __ EnterExitFrame(); |
+ __ EnterExitFrame(save_doubles()); |
// ebx: pointer to C function (C callee-saved) |
// ebp: frame pointer (restored after C call) |
@@ -2066,7 +2086,7 @@ void CEntryStub::Generate(MacroAssembler* masm) { |
} |
// Exit the JavaScript to C++ exit frame. |
- __ LeaveExitFrame(); |
+ __ LeaveExitFrame(save_doubles()); |
__ ret(0); |
// Handling of exception. |
@@ -3545,6 +3565,8 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( |
Isolate* isolate) { |
StoreBufferOverflowStub stub(isolate, kDontSaveFPRegs); |
stub.GetCode(); |
+ StoreBufferOverflowStub stub2(isolate, kSaveFPRegs); |
+ stub2.GetCode(); |
} |
@@ -3564,7 +3586,7 @@ void RecordWriteStub::Generate(MacroAssembler* masm) { |
__ jmp(&skip_to_incremental_compacting, Label::kFar); |
if (remembered_set_action() == EMIT_REMEMBERED_SET) { |
- __ RememberedSetHelper(object(), address(), value(), |
+ __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(), |
MacroAssembler::kReturnAtEnd); |
} else { |
__ ret(0); |
@@ -3608,7 +3630,7 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) { |
mode); |
InformIncrementalMarker(masm); |
regs_.Restore(masm); |
- __ RememberedSetHelper(object(), address(), value(), |
+ __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(), |
MacroAssembler::kReturnAtEnd); |
__ bind(&dont_need_remembered_set); |
@@ -3625,7 +3647,7 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) { |
void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { |
- regs_.SaveCallerSaveRegisters(masm); |
+ regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode()); |
int argument_count = 3; |
__ PrepareCallCFunction(argument_count, regs_.scratch0()); |
__ mov(Operand(esp, 0 * kPointerSize), regs_.object()); |
@@ -3638,7 +3660,7 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { |
ExternalReference::incremental_marking_record_write_function(isolate()), |
argument_count); |
- regs_.RestoreCallerSaveRegisters(masm); |
+ regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode()); |
} |
@@ -3669,7 +3691,7 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( |
regs_.Restore(masm); |
if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { |
- __ RememberedSetHelper(object(), address(), value(), |
+ __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(), |
MacroAssembler::kReturnAtEnd); |
} else { |
__ ret(0); |
@@ -3714,7 +3736,7 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( |
regs_.Restore(masm); |
if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) { |
- __ RememberedSetHelper(object(), address(), value(), |
+ __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(), |
MacroAssembler::kReturnAtEnd); |
} else { |
__ ret(0); |
@@ -3785,6 +3807,7 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { |
__ mov(Operand(ecx, 0), eax); |
// Update the write barrier for the array store. |
__ RecordWrite(ebx, ecx, eax, |
+ kDontSaveFPRegs, |
EMIT_REMEMBERED_SET, |
OMIT_SMI_CHECK); |
__ ret(0); |
@@ -3814,7 +3837,7 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { |
void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { |
- CEntryStub ces(isolate(), 1); |
+ CEntryStub ces(isolate(), 1, kSaveFPRegs); |
__ call(ces.GetCode(), RelocInfo::CODE_TARGET); |
int parameter_count_offset = |
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; |