MIPS: Improve registers saving for safepoints in deferred code.

This reduces code size of initial snapshot by more than 25Kb.

Registers are saved or restored via common stubs, instead of doing it
through inlined push/pop instructions (one instruction per register) in
generated deferred code.

TEST=
BUG=
R=jkummerow@chromium.org, plind44@gmail.com

Review URL: https://codereview.chromium.org/109653013

Patch from Dusan Milosavljevic <Dusan.Milosavljevic@rt-rk.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18399 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
plind44@gmail.com 2013-12-20 19:44:03 +00:00
parent 44b69b079f
commit 21daecb611
4 changed files with 97 additions and 9 deletions

View File

@ -114,7 +114,9 @@ namespace internal {
#if V8_TARGET_ARCH_MIPS
#define CODE_STUB_LIST_MIPS(V) \
V(RegExpCEntry) \
V(DirectCEntry)
V(DirectCEntry) \
V(StoreRegistersState) \
V(RestoreRegistersState)
#else
#define CODE_STUB_LIST_MIPS(V)
#endif

View File

@ -1234,6 +1234,31 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
}
void StoreRegistersStateStub::Generate(MacroAssembler* masm) {
__ mov(t9, ra);
__ pop(ra);
if (save_doubles_ == kSaveFPRegs) {
__ PushSafepointRegistersAndDoubles();
} else {
__ PushSafepointRegisters();
}
__ Jump(t9);
}
void RestoreRegistersStateStub::Generate(MacroAssembler* masm) {
__ mov(t9, ra);
__ pop(ra);
__ StoreToSafepointRegisterSlot(t9, t9);
if (save_doubles_ == kSaveFPRegs) {
__ PopSafepointRegistersAndDoubles();
} else {
__ PopSafepointRegisters();
}
__ Jump(t9);
}
void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
// We don't allow a GC during a store buffer overflow so there is no need to
// store the registers in any particular way, but we do have to store and
@ -1501,6 +1526,28 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
BinaryOpICStub::GenerateAheadOfTime(isolate);
StoreRegistersStateStub::GenerateAheadOfTime(isolate);
RestoreRegistersStateStub::GenerateAheadOfTime(isolate);
}
void StoreRegistersStateStub::GenerateAheadOfTime(
Isolate* isolate) {
StoreRegistersStateStub stub1(kDontSaveFPRegs);
stub1.GetCode(isolate);
// Hydrogen code stubs need stub2 at snapshot time.
StoreRegistersStateStub stub2(kSaveFPRegs);
stub2.GetCode(isolate);
}
void RestoreRegistersStateStub::GenerateAheadOfTime(
Isolate* isolate) {
RestoreRegistersStateStub stub1(kDontSaveFPRegs);
stub1.GetCode(isolate);
// Hydrogen code stubs need stub2 at snapshot time.
RestoreRegistersStateStub stub2(kSaveFPRegs);
stub2.GetCode(isolate);
}

View File

@ -157,6 +157,33 @@ class SubStringStub: public PlatformCodeStub {
void Generate(MacroAssembler* masm);
};
class StoreRegistersStateStub: public PlatformCodeStub {
public:
explicit StoreRegistersStateStub(SaveFPRegsMode with_fp)
: save_doubles_(with_fp) {}
static void GenerateAheadOfTime(Isolate* isolate);
private:
Major MajorKey() { return StoreRegistersState; }
int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
SaveFPRegsMode save_doubles_;
void Generate(MacroAssembler* masm);
};
class RestoreRegistersStateStub: public PlatformCodeStub {
public:
explicit RestoreRegistersStateStub(SaveFPRegsMode with_fp)
: save_doubles_(with_fp) {}
static void GenerateAheadOfTime(Isolate* isolate);
private:
Major MajorKey() { return RestoreRegistersState; }
int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
SaveFPRegsMode save_doubles_;
void Generate(MacroAssembler* masm);
};
class StringCompareStub: public PlatformCodeStub {
public:

View File

@ -422,12 +422,18 @@ class LCodeGen: public LCodeGenBase {
codegen_->expected_safepoint_kind_ = kind;
switch (codegen_->expected_safepoint_kind_) {
case Safepoint::kWithRegisters:
codegen_->masm_->PushSafepointRegisters();
case Safepoint::kWithRegisters: {
StoreRegistersStateStub stub1(kDontSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub1);
break;
case Safepoint::kWithRegistersAndDoubles:
codegen_->masm_->PushSafepointRegistersAndDoubles();
}
case Safepoint::kWithRegistersAndDoubles: {
StoreRegistersStateStub stub2(kSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub2);
break;
}
default:
UNREACHABLE();
}
@ -437,12 +443,18 @@ class LCodeGen: public LCodeGenBase {
Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
ASSERT((kind & Safepoint::kWithRegisters) != 0);
switch (kind) {
case Safepoint::kWithRegisters:
codegen_->masm_->PopSafepointRegisters();
case Safepoint::kWithRegisters: {
RestoreRegistersStateStub stub1(kDontSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub1);
break;
case Safepoint::kWithRegistersAndDoubles:
codegen_->masm_->PopSafepointRegistersAndDoubles();
}
case Safepoint::kWithRegistersAndDoubles: {
RestoreRegistersStateStub stub2(kSaveFPRegs);
codegen_->masm_->push(ra);
codegen_->masm_->CallStub(&stub2);
break;
}
default:
UNREACHABLE();
}