From 0c73bb07e6c88a40528f4fb088075a99ac9ec3a5 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 28 May 2010 00:30:35 -0700 Subject: [PATCH] [JAEGER] Jumps in-between the slow and fast paths now work. --- js/src/methodjit/Compiler.cpp | 9 ++++--- js/src/methodjit/StubCompiler.cpp | 39 +++++++++++++++++++++++-------- js/src/methodjit/StubCompiler.h | 10 +++++--- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 6f1ccd20652..9acf069550a 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -195,7 +195,10 @@ mjit::Compiler::finishThisUp() memcpy(result, masm.buffer(), masm.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); stubcc.finalize(result + masm.size()); @@ -449,7 +452,7 @@ mjit::Compiler::emitReturn() void mjit::Compiler::prepareStubCall() { - JaegerSpew(JSpew_Insns, " ---- SLOW CALL, SYNCING FRAME ---- \n"); + JaegerSpew(JSpew_Insns, " ---- STUB CALL, SYNCING FRAME ---- \n"); frame.sync(); JaegerSpew(JSpew_Insns, " ---- KILLING TEMP REGS ---- \n"); frame.killSyncedRegs(Registers::TempRegs); @@ -462,7 +465,7 @@ mjit::Compiler::stubCall(void *ptr, Uses uses, Defs defs) frame.forget(uses.nuses); JaegerSpew(JSpew_Insns, " ---- CALLING STUB ---- \n"); 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; } diff --git a/js/src/methodjit/StubCompiler.cpp b/js/src/methodjit/StubCompiler.cpp index 69e9323e956..494f5ea2b67 100644 --- a/js/src/methodjit/StubCompiler.cpp +++ b/js/src/methodjit/StubCompiler.cpp @@ -40,37 +40,43 @@ #include "StubCompiler.h" #include "Compiler.h" +#include "assembler/assembler/LinkBuffer.h" using namespace js; using namespace mjit; 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 StubCompiler::linkExit(Jump j) { - /* :TODO: oom check */ - exits.append(ExitPatch(j, masm.label())); + exits.append(CrossPatch(j, masm.label())); } void StubCompiler::leave() { - JaegerSpew(JSpew_Insns, " ---- BEGIN STUB SPILL CODE ---- \n"); + JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW SPILL CODE ---- \n"); frame.sync(masm, snapshot); - JaegerSpew(JSpew_Insns, " ---- END STUB SPILL CODE ---- \n"); - JaegerSpew(JSpew_Insns, " ---- BEGIN STUB CALL CODE ---- \n"); + JaegerSpew(JSpew_Insns, " ---- END SLOW SPILL CODE ---- \n"); + JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n"); } void 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); - 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; @@ -81,12 +87,25 @@ JSC::MacroAssembler::Call StubCompiler::stubCall(void *ptr) { 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; } 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); } diff --git a/js/src/methodjit/StubCompiler.h b/js/src/methodjit/StubCompiler.h index 083f55055f9..4f7a622c880 100644 --- a/js/src/methodjit/StubCompiler.h +++ b/js/src/methodjit/StubCompiler.h @@ -58,8 +58,8 @@ class StubCompiler typedef JSC::MacroAssembler::Jump Jump; typedef JSC::MacroAssembler::Label Label; - struct ExitPatch { - ExitPatch(Jump from, Label to) + struct CrossPatch { + CrossPatch(Jump from, Label to) : from(from), to(to) { } @@ -72,9 +72,12 @@ class StubCompiler FrameState &frame; JSScript *script; Assembler masm; - Vector exits; RegSnapshot snapshot; + /* :TODO: oom check */ + Vector exits; + Vector joins; + public: StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame, JSScript *script); @@ -112,6 +115,7 @@ class StubCompiler void rejoin(uint32 invalidationDepth); /* Finish all native code patching. */ + void fixCrossJumps(uint8 *ncode, size_t offset, size_t total); void finalize(uint8 *ncode); private: