| 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;
|
|
|