[JAEGER] Jumps in-between the slow and fast paths now work.

This commit is contained in:
David Anderson 2010-05-28 00:30:35 -07:00
parent 597c9c7210
commit 0c73bb07e6
3 changed files with 42 additions and 16 deletions

View File

@ -195,7 +195,10 @@ mjit::Compiler::finishThisUp()
memcpy(result, masm.buffer(), masm.size()); memcpy(result, masm.buffer(), masm.size());
memcpy(result + masm.size(), stubcc.buffer(), stubcc.size()); memcpy(result + masm.size(), stubcc.buffer(), stubcc.size());
/* Patch up stub calls. */ /* Link fast and slow paths together. */
stubcc.fixCrossJumps(result, masm.size(), masm.size() + stubcc.size());
/* Patch all outgoing calls. */
masm.finalize(result); masm.finalize(result);
stubcc.finalize(result + masm.size()); stubcc.finalize(result + masm.size());
@ -449,7 +452,7 @@ mjit::Compiler::emitReturn()
void void
mjit::Compiler::prepareStubCall() mjit::Compiler::prepareStubCall()
{ {
JaegerSpew(JSpew_Insns, " ---- SLOW CALL, SYNCING FRAME ---- \n"); JaegerSpew(JSpew_Insns, " ---- STUB CALL, SYNCING FRAME ---- \n");
frame.sync(); frame.sync();
JaegerSpew(JSpew_Insns, " ---- KILLING TEMP REGS ---- \n"); JaegerSpew(JSpew_Insns, " ---- KILLING TEMP REGS ---- \n");
frame.killSyncedRegs(Registers::TempRegs); frame.killSyncedRegs(Registers::TempRegs);
@ -462,7 +465,7 @@ mjit::Compiler::stubCall(void *ptr, Uses uses, Defs defs)
frame.forget(uses.nuses); frame.forget(uses.nuses);
JaegerSpew(JSpew_Insns, " ---- CALLING STUB ---- \n"); JaegerSpew(JSpew_Insns, " ---- CALLING STUB ---- \n");
Call cl = masm.stubCall(ptr, PC, frame.stackDepth() + script->nfixed); Call cl = masm.stubCall(ptr, PC, frame.stackDepth() + script->nfixed);
JaegerSpew(JSpew_Insns, " ---- END SLOW CALL ---- \n"); JaegerSpew(JSpew_Insns, " ---- END STUB CALL ---- \n");
return cl; return cl;
} }

View File

@ -40,37 +40,43 @@
#include "StubCompiler.h" #include "StubCompiler.h"
#include "Compiler.h" #include "Compiler.h"
#include "assembler/assembler/LinkBuffer.h"
using namespace js; using namespace js;
using namespace mjit; using namespace mjit;
StubCompiler::StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame, JSScript *script) StubCompiler::StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame, JSScript *script)
: cx(cx), cc(cc), frame(frame), script(script), exits(SystemAllocPolicy()) : cx(cx), cc(cc), frame(frame), script(script), exits(SystemAllocPolicy()),
joins(SystemAllocPolicy())
{ {
} }
void void
StubCompiler::linkExit(Jump j) StubCompiler::linkExit(Jump j)
{ {
/* :TODO: oom check */ exits.append(CrossPatch(j, masm.label()));
exits.append(ExitPatch(j, masm.label()));
} }
void void
StubCompiler::leave() StubCompiler::leave()
{ {
JaegerSpew(JSpew_Insns, " ---- BEGIN STUB SPILL CODE ---- \n"); JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW SPILL CODE ---- \n");
frame.sync(masm, snapshot); frame.sync(masm, snapshot);
JaegerSpew(JSpew_Insns, " ---- END STUB SPILL CODE ---- \n"); JaegerSpew(JSpew_Insns, " ---- END SLOW SPILL CODE ---- \n");
JaegerSpew(JSpew_Insns, " ---- BEGIN STUB CALL CODE ---- \n"); JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n");
} }
void void
StubCompiler::rejoin(uint32 invalidationDepth) StubCompiler::rejoin(uint32 invalidationDepth)
{ {
JaegerSpew(JSpew_Insns, " ---- BEGIN STUB RESTORE CODE ---- \n"); JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW RESTORE CODE ---- \n");
frame.merge(masm, snapshot, invalidationDepth); frame.merge(masm, snapshot, invalidationDepth);
JaegerSpew(JSpew_Insns, " ---- END STUB RESTORE CODE ---- \n");
Jump j = masm.jump();
joins.append(CrossPatch(j, cc.getLabel()));
JaegerSpew(JSpew_Insns, " ---- END SLOW RESTORE CODE ---- \n");
} }
typedef JSC::MacroAssembler::RegisterID RegisterID; typedef JSC::MacroAssembler::RegisterID RegisterID;
@ -81,12 +87,25 @@ JSC::MacroAssembler::Call
StubCompiler::stubCall(void *ptr) StubCompiler::stubCall(void *ptr)
{ {
Call cl = masm.stubCall(ptr, cc.getPC(), frame.stackDepth() + script->nfixed); Call cl = masm.stubCall(ptr, cc.getPC(), frame.stackDepth() + script->nfixed);
JaegerSpew(JSpew_Insns, " ---- END STUB CALL CODE ---- \n"); JaegerSpew(JSpew_Insns, " ---- END SLOW CALL CODE ---- \n");
return cl; return cl;
} }
void void
StubCompiler::finalize(uint8* ncode) StubCompiler::fixCrossJumps(uint8 *ncode, size_t offset, size_t total)
{
JSC::LinkBuffer fast(ncode, total);
JSC::LinkBuffer slow(ncode + offset, total - offset);
for (size_t i = 0; i < exits.length(); i++)
fast.link(exits[i].from, slow.locationOf(exits[i].to));
for (size_t i = 0; i < joins.length(); i++)
slow.link(joins[i].from, fast.locationOf(joins[i].to));
}
void
StubCompiler::finalize(uint8 *ncode)
{ {
masm.finalize(ncode); masm.finalize(ncode);
} }

View File

@ -58,8 +58,8 @@ class StubCompiler
typedef JSC::MacroAssembler::Jump Jump; typedef JSC::MacroAssembler::Jump Jump;
typedef JSC::MacroAssembler::Label Label; typedef JSC::MacroAssembler::Label Label;
struct ExitPatch { struct CrossPatch {
ExitPatch(Jump from, Label to) CrossPatch(Jump from, Label to)
: from(from), to(to) : from(from), to(to)
{ } { }
@ -72,9 +72,12 @@ class StubCompiler
FrameState &frame; FrameState &frame;
JSScript *script; JSScript *script;
Assembler masm; Assembler masm;
Vector<ExitPatch, 64, SystemAllocPolicy> exits;
RegSnapshot snapshot; RegSnapshot snapshot;
/* :TODO: oom check */
Vector<CrossPatch, 64, SystemAllocPolicy> exits;
Vector<CrossPatch, 64, SystemAllocPolicy> joins;
public: public:
StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame, JSScript *script); StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame, JSScript *script);
@ -112,6 +115,7 @@ class StubCompiler
void rejoin(uint32 invalidationDepth); void rejoin(uint32 invalidationDepth);
/* Finish all native code patching. */ /* Finish all native code patching. */
void fixCrossJumps(uint8 *ncode, size_t offset, size_t total);
void finalize(uint8 *ncode); void finalize(uint8 *ncode);
private: private: