Commit 21daecb6 authored by plind44@gmail.com's avatar plind44@gmail.com

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
parent 44b69b07
......@@ -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
......
......@@ -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);
}
......
......@@ -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:
......
......@@ -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();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment