author | David Anderson <danderson@mozilla.com> |
Wed, 26 May 2010 17:08:08 -0700 | |
changeset 52608 | 0b9cfe5ef098f9ad8a87b36e535f9e8df4fe99d8 |
parent 52607 | ec13cf65e503515e790747c410990f3af34916db |
child 52609 | a6edb3f0d569ec5e339047cf800abd04c96d4dfc |
push id | 1 |
push user | root |
push date | Tue, 26 Apr 2011 22:38:44 +0000 |
treeherder | mozilla-beta@bfdb6e623a36 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 1.9.3a5pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
|
--- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -295,21 +295,22 @@ CPPSRCS += Assertions.cpp \ ExecutableAllocatorPosix.cpp \ ExecutableAllocatorWin.cpp \ ExecutableAllocator.cpp \ ARMAssembler.cpp \ MacroAssemblerARM.cpp \ MethodJIT.cpp \ BytecodeAnalyzer.cpp \ Logging.cpp \ - Stubs.cpp \ + StubCalls.cpp \ Compiler.cpp \ CodeGenerator.cpp \ FrameState.cpp \ FastOps.cpp \ + StubCompiler.cpp \ $(NULL) # PICStubCompiler.cpp \ ifeq (86, $(findstring 86,$(TARGET_CPU))) ifeq (x86_64, $(TARGET_CPU)) ifeq ($(OS_ARCH),WINNT) ASFILES += TrampolineMasmX64.asm endif
--- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -58,17 +58,17 @@ static const char *OpcodeNames[] = { #if ENABLE_ASSEMBLER && WTF_CPU_X86 && !WTF_PLATFORM_MAC JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2; #endif mjit::Compiler::Compiler(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain) : cx(cx), script(script), scopeChain(scopeChain), globalObj(scopeChain->getGlobal()), fun(fun), analysis(cx, script), jumpMap(NULL), frame(cx, script, masm), cg(masm, frame), - branchPatches(ContextAllocPolicy(cx)) + branchPatches(ContextAllocPolicy(cx)), stubcc(cx, *this, frame, script) { } #define CHECK_STATUS(expr) \ JS_BEGIN_MACRO \ CompileStatus status_ = (expr); \ if (status_ != Compile_Okay) \ return status_; \
--- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -39,30 +39,29 @@ * ***** END LICENSE BLOCK ***** */ #if !defined jsjaeger_compiler_h__ && defined JS_METHODJIT #define jsjaeger_compiler_h__ #include "jscntxt.h" #include "jstl.h" #include "BytecodeAnalyzer.h" #include "MethodJIT.h" -#include "assembler/assembler/MacroAssembler.h" #include "CodeGenIncludes.h" +#include "StubCompiler.h" namespace js { namespace mjit { class Compiler { typedef JSC::MacroAssembler::Label Label; typedef JSC::MacroAssembler::ImmPtr ImmPtr; typedef JSC::MacroAssembler::RegisterID RegisterID; typedef JSC::MacroAssembler::Address Address; typedef JSC::MacroAssembler::Jump Jump; - typedef JSC::MacroAssembler MacroAssembler; struct BranchPatch { BranchPatch(const Jump &j, jsbytecode *pc) : jump(j), pc(pc) { } Jump jump; jsbytecode *pc; @@ -71,31 +70,34 @@ class Compiler JSContext *cx; JSScript *script; JSObject *scopeChain; JSObject *globalObj; JSFunction *fun; BytecodeAnalyzer analysis; Label *jumpMap; jsbytecode *PC; - MacroAssembler masm; + Assembler masm; FrameState frame; CodeGenerator cg; js::Vector<BranchPatch, 64> branchPatches; + StubCompiler stubcc; public: // Special atom index used to indicate that the atom is 'length'. This // follows interpreter usage in JSOP_LENGTH. enum { LengthAtomIndex = uint32(-2) }; Compiler(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain); ~Compiler(); CompileStatus Compile(); + jsbytecode *getPC() { return PC; } + private: CompileStatus generatePrologue(); CompileStatus generateMethod(); CompileStatus generateEpilogue(); CompileStatus finishThisUp(); /* Non-emitting helpers. */ const Label &labelOf(jsbytecode *pc);
--- a/js/src/methodjit/MachineRegs.h +++ b/js/src/methodjit/MachineRegs.h @@ -46,16 +46,32 @@ namespace js { namespace mjit { struct Registers { typedef JSC::MacroAssembler::RegisterID RegisterID; +#if defined(JS_CPU_X86) || defined(JS_CPU_X64) + static const RegisterID ReturnReg = JSC::X86Registers::eax; +# if defined(JS_CPU_X86) || defined(_MSC_VER) + static const RegisterID ArgReg0 = JSC::X86Registers::ecx; + static const RegisterID ArgReg1 = JSC::X86Registers::edx; +# else + static const RegisterID ArgReg0 = JSC::X86Registers::edi; + static const RegisterID ArgReg1 = JSC::X86Registers::esi; +# endif +#elif JS_CPU_ARM + static const RegisterID ReturnReg = JSC::ARMRegisters::r0; + static const RegisterID ArgReg0 = JSC::ARMRegisters::r0; + static const RegisterID ArgReg1 = JSC::ARMRegisters::r1; +#endif + + static inline uint32 maskReg(RegisterID reg) { return (1 << reg); } static inline uint32 mask2Regs(RegisterID reg1, RegisterID reg2) { return maskReg(reg1) | maskReg(reg2); } @@ -118,19 +134,23 @@ struct Registers { static const uint32 SingleByteRegs = TempRegs | SavedRegs; #else # error "Unsupported platform" #endif static const uint32 AvailRegs = SavedRegs | TempRegs; - Registers() : freeMask(AvailRegs) - { - } + Registers() + : freeMask(AvailRegs) + { } + + Registers(uint32 freeMask) + : freeMask(freeMask) + { } void reset() { freeMask = AvailRegs; } bool anyRegsFree() { return !!freeMask; }
--- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -66,20 +66,16 @@ struct VMFrame #if defined(JS_CPU_X86) uintptr_t padding[2]; #elif defined(JS_CPU_ARM) uintptr_t padding; #endif union Arguments { - struct BINDNAME { - uint32 index; - JSObject *obj; - } bindname; struct DEFVAR { jsatomid index; uint32 op; } defvar; struct LAMBDA { uint32 index; JSOp op; } lambda;
--- a/js/src/methodjit/RematInfo.h +++ b/js/src/methodjit/RematInfo.h @@ -74,20 +74,22 @@ struct RematInfo { location_ = PhysLoc_Memory; } void setConstant() { location_ = PhysLoc_Constant; } bool isCopy() { return location_ == PhysLoc_Copy; } bool isConstant() { return location_ == PhysLoc_Constant; } bool inRegister() { return location_ == PhysLoc_Register; } + bool inMemory() { return location_ == PhysLoc_Memory; } RegisterID reg() { return reg_; } void unsync() { synced_ = false; } bool synced() { return synced_; } + bool needsSync() { return !inMemory() && !synced(); } /* Set if location is PhysLoc_Register. */ RegisterID reg_; /* Remat source. */ PhysLoc location_; /* Whether or not the value has been synced to memory. */
rename from js/src/methodjit/Stubs.cpp rename to js/src/methodjit/StubCalls.cpp --- a/js/src/methodjit/Stubs.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -47,17 +47,17 @@ #include "jsiter.h" #include "jsnum.h" #include "jsxml.h" #include "jsstaticcheck.h" #include "jsbool.h" #include "assembler/assembler/MacroAssemblerCodeRef.h" #include "jsiter.h" #include "jstypes.h" -#include "methodjit/Stubs.h" +#include "methodjit/StubCalls.h" #include "jstracer.h" #include "jspropertycache.h" #include "jspropertycacheinlines.h" #include "jsscopeinlines.h" #include "jsscriptinlines.h" #include "jsstrinlines.h" #include "jsobjinlines.h" #include "jscntxtinlines.h" @@ -77,16 +77,39 @@ using namespace JSC; #define THROWV(v) \ do { \ void *ptr = JS_FUNC_TO_DATA_PTR(void *, JaegerThrowpoline); \ f.setReturnAddress(ReturnAddressPtr(FunctionPtr(ptr))); \ return v; \ } while (0) +JSObject * JS_FASTCALL +mjit::stubs::BindName(VMFrame &f) +{ + PropertyCacheEntry *entry; + + /* Fast-path should have caught this. See comment in interpreter. */ + JS_ASSERT(f.fp->scopeChain->getParent()); + + JSAtom *atom; + JSObject *obj2; + JSContext *cx = f.cx; + JSObject *obj = f.fp->scopeChain->getParent(); + JS_PROPERTY_CACHE(cx).test(cx, f.regs.pc, obj, obj2, entry, atom); + if (!atom) + return obj; + + jsid id = ATOM_TO_JSID(atom); + obj = js_FindIdentifierBase(cx, f.fp->scopeChain, id); + if (!obj) + THROWV(NULL); + return obj; +} + static bool InlineReturn(JSContext *cx) { bool ok = true; JSStackFrame *fp = cx->fp; JS_ASSERT(!fp->blockChain);
rename from js/src/methodjit/Stubs.h rename to js/src/methodjit/StubCalls.h --- a/js/src/methodjit/Stubs.h +++ b/js/src/methodjit/StubCalls.h @@ -43,16 +43,17 @@ #include "MethodJIT.h" namespace js { namespace mjit { namespace stubs { void * JS_FASTCALL Return(VMFrame &f); +JSObject * JS_FASTCALL BindName(VMFrame &f); }}} /* namespace stubs,mjit,js */ extern "C" void * js_InternalThrow(js::VMFrame &f); #endif /* jslogic_h__ */
new file mode 100644 --- /dev/null +++ b/js/src/methodjit/StubCompiler.cpp @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=4 sw=4 et tw=99: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released + * May 28, 2008. + * + * The Initial Developer of the Original Code is + * Brendan Eich <brendan@mozilla.org> + * + * Contributor(s): + * David Anderson <danderson@mozilla.com> + * David Mandelin <dmandelin@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "StubCompiler.h" +#include "Compiler.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(ContextAllocPolicy(cx)) +{ +} + +void +StubCompiler::linkExit(Jump j) +{ + /* :TODO: oom check */ + exits.append(ExitPatch(j, masm.label())); +} + +void +StubCompiler::syncAndSpill() +{ + frame.sync(masm); +} + +void * +StubCompiler::getCallTarget(void *fun) +{ +#ifdef JS_CPU_ARM + /* + * Insert a veneer for ARM to allow it to catch exceptions. There is no + * reliable way to determine the location of the return address on the + * stack, so it cannot be hijacked. + * + * :TODO: It wouldn't surprise me if GCC always pushes LR first. In that + * case, this looks like the x86-style call, and we can hijack the stack + * slot accordingly, thus avoiding the cost of a veneer. This should be + * investigated. + */ + + void *pfun = JS_FUNC_TO_DATA_PTR(void *, JaegerStubVeneer); + + /* + * We put the real target address into IP, as this won't conflict with + * the EABI argument-passing mechanism. Technically, this isn't ABI- + * compliant. + */ + masm.move(Imm32(intptr_t(fun)), ARMRegisters::ip); +#else + /* + * Architectures that push the return address to an easily-determined + * location on the stack can hijack C++'s return mechanism by overwriting + * that address, so a veneer is not required. + */ + void *pfun = fun; +#endif + return pfun; +} + +typedef JSC::MacroAssembler::RegisterID RegisterID; +typedef JSC::MacroAssembler::ImmPtr ImmPtr; +typedef JSC::MacroAssembler::Imm32 Imm32; + +/* Need a temp reg that is not ArgReg1. */ +#if defined(JS_CPU_X86) || defined(JS_CPU_ARM) +static const RegisterID ClobberInCall = JSC::X86Registers::ecx; +#elif defined(JS_CPU_ARM) +static const RegisterID ClobberInCall = JSC::ARMRegisters::r2; +#endif + +JS_STATIC_ASSERT(ClobberInCall != Registers::ArgReg1); + +void +StubCompiler::scall(void *ptr) +{ + /* PC -> regs->pc :( */ + masm.storePtr(ImmPtr(cc.getPC()), + FrameAddress(offsetof(VMFrame, regs) + offsetof(JSFrameRegs, pc))); + + /* sp = fp + slots() + stackDepth */ + masm.addPtr(Imm32(sizeof(JSStackFrame) + + (frame.stackDepth() + script->nfixed) * sizeof(jsval)), + FrameState::FpReg, ClobberInCall); + + /* regs->sp = sp */ + masm.storePtr(ClobberInCall, + FrameAddress(offsetof(VMFrame, regs) + offsetof(JSFrameRegs, sp))); + + /* VMFrame -> ArgReg0 */ + masm.move(Assembler::stackPointerRegister, Registers::ArgReg0); +} +
new file mode 100644 --- /dev/null +++ b/js/src/methodjit/StubCompiler.h @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=4 sw=4 et tw=99: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released + * May 28, 2008. + * + * The Initial Developer of the Original Code is + * Brendan Eich <brendan@mozilla.org> + * + * Contributor(s): + * David Anderson <danderson@mozilla.com> + * David Mandelin <dmandelin@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#if !defined(jsstub_compiler_h__) && defined(JS_METHODJIT) +#define jsstub_compiler_h__ + +#include "jscntxt.h" +#include "jstl.h" +#include "MethodJIT.h" +#include "methodjit/nunbox/Assembler.h" +#include "CodeGenIncludes.h" + +namespace js { +namespace mjit { + +class Compiler; + +struct StubCallInfo { + uint32 numSpills; +}; + +class StubCompiler +{ + typedef JSC::MacroAssembler::Jump Jump; + typedef JSC::MacroAssembler::Label Label; + + struct ExitPatch { + ExitPatch(Jump from, Label to) + : from(from), to(to) + { } + + Jump from; + Label to; + }; + + JSContext *cx; + Compiler &cc; + FrameState &frame; + JSScript *script; + Assembler masm; + Vector<ExitPatch, 64, ContextAllocPolicy> exits; + + public: + StubCompiler(JSContext *cx, mjit::Compiler &cc, FrameState &frame, JSScript *script); + void linkExit(Jump j); + void syncAndSpill(); + void call(JSObjStub stub) { scall(JS_FUNC_TO_DATA_PTR(void *, stub)); } + + private: + void scall(void *ptr); + void *getCallTarget(void *fun); +}; + +} /* namepsace mjit */ +} /* namespace js */ + +#endif /* jsstub_compiler_h__ */ +
new file mode 100644 --- /dev/null +++ b/js/src/methodjit/nunbox/Assembler.h @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=4 sw=4 et tw=99: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released + * May 28, 2008. + * + * The Initial Developer of the Original Code is + * Brendan Eich <brendan@mozilla.org> + * + * Contributor(s): + * David Anderson <danderson@mozilla.com> + * David Mandelin <dmandelin@mozilla.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#if !defined jsjaeger_assembler_h__ && defined JS_METHODJIT +#define jsjaeger_assembler_h__ + +#include "assembler/assembler/MacroAssembler.h" + +namespace js { +namespace mjit { + +class Assembler : public JSC::MacroAssembler +{ + public: +}; + +} /* namespace js */ +} /* namespace mjit */ + +#endif
--- a/js/src/methodjit/nunbox/CodeGenerator.cpp +++ b/js/src/methodjit/nunbox/CodeGenerator.cpp @@ -52,17 +52,17 @@ static const uint32 PAYLOAD_OFFSET = 0; class ImmIntPtr : public JSC::MacroAssembler::ImmPtr { public: ImmIntPtr(int64_t i64) : ImmPtr(reinterpret_cast<void*>(i64)) { } }; -CodeGenerator::CodeGenerator(MacroAssembler &masm, FrameState &frame) +CodeGenerator::CodeGenerator(Assembler &masm, FrameState &frame) : masm(masm), frame(frame) { } void CodeGenerator::storeJsval(const Value &v, Address address) { jsval_layout jv;
--- a/js/src/methodjit/nunbox/CodeGenerator.h +++ b/js/src/methodjit/nunbox/CodeGenerator.h @@ -39,34 +39,33 @@ * ***** END LICENSE BLOCK ***** */ #if !defined jsjaeger_codegen_h__ && defined JS_METHODJIT #define jsjaeger_codegen_h__ #include "jscntxt.h" #include "jstl.h" #include "methodjit/MethodJIT.h" #include "methodjit/nunbox/FrameState.h" -#include "assembler/assembler/MacroAssembler.h" +#include "methodjit/nunbox/Assembler.h" namespace js { namespace mjit { class CodeGenerator { - typedef JSC::MacroAssembler MacroAssembler; typedef JSC::MacroAssembler::Address Address; typedef JSC::MacroAssembler::Imm32 Imm32; typedef JSC::MacroAssembler::ImmPtr ImmPtr; typedef JSC::MacroAssembler::RegisterID RegisterID; - MacroAssembler &masm; + Assembler &masm; FrameState &frame; public: - CodeGenerator(MacroAssembler &masm, FrameState &frame); + CodeGenerator(Assembler &masm, FrameState &frame); void storeValue(FrameEntry *vi, Address address, bool popped); void storeJsval(const Value &v, Address address); void pushValueOntoFrame(Address address); }; } /* namespace js */ } /* namespace mjit */
--- a/js/src/methodjit/nunbox/FastOps.cpp +++ b/js/src/methodjit/nunbox/FastOps.cpp @@ -34,34 +34,38 @@ * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "methodjit/MethodJIT.h" #include "methodjit/Compiler.h" +#include "methodjit/StubCalls.h" #include "jsautooplen.h" using namespace js; +using namespace js::mjit; static const uint32 TAG_OFFSET = 4; static const uint32 PAYLOAD_OFFSET = 0; void mjit::Compiler::jsop_bindname(uint32 index) { RegisterID reg = frame.allocReg(); masm.loadPtr(Address(FrameState::FpReg, offsetof(JSStackFrame, scopeChain)), reg); Address address(reg, offsetof(JSObject, fslots) + JSSLOT_PARENT * sizeof(jsval)); masm.load32(Address(address.base, address.offset + PAYLOAD_OFFSET), reg); -#ifdef JS_64BIT -# error "Bleh!" -#endif + Jump j = masm.branchTestPtr(Assembler::Zero, reg, reg); - Jump j = masm.branchTestPtr(MacroAssembler::Zero, reg, reg); + { + stubcc.linkExit(j); + stubcc.syncAndSpill(); + stubcc.call(stubs::BindName); + } frame.pushObject(reg); }
--- a/js/src/methodjit/nunbox/FrameState.cpp +++ b/js/src/methodjit/nunbox/FrameState.cpp @@ -112,8 +112,51 @@ FrameState::invalidate(FrameEntry *fe) void FrameState::flush() { for (FrameEntry *fe = base; fe < sp; fe++) invalidate(fe); } +void +FrameState::syncRegister(Assembler &masm, RegisterID reg, const RegState &state) const +{ + JS_NOT_REACHED("bleh"); +} + +void +FrameState::syncType(FrameEntry *fe, Assembler &masm) const +{ +} + +void +FrameState::syncData(FrameEntry *fe, Assembler &masm) const +{ +} + +void +FrameState::sync(Assembler &masm) const +{ + for (FrameEntry *fe = base; fe < sp; fe++) { + if (fe->type.needsSync()) + syncType(fe, masm); + if (fe->data.needsSync()) + syncData(fe, masm); + } +} + +void +FrameState::restoreTempRegs(Assembler &masm) const +{ +#if 0 + /* Get a mask of all allocated registers that must be synced. */ + Registers temps = regalloc.freeMask & Registers::TempRegs; + + while (temps.anyRegsFree()) { + RegisterID reg = temps.allocReg(); + if (!regstate[reg].tracked) + continue; + syncRegister(masm, reg, regstate[reg]); + } +#endif +} +
--- a/js/src/methodjit/nunbox/FrameState.h +++ b/js/src/methodjit/nunbox/FrameState.h @@ -37,26 +37,33 @@ * * ***** END LICENSE BLOCK ***** */ #if !defined jsjaeger_framestate_h__ && defined JS_METHODJIT #define jsjaeger_framestate_h__ #include "jsapi.h" #include "methodjit/MachineRegs.h" -#include "assembler/assembler/MacroAssembler.h" +#include "methodjit/nunbox/Assembler.h" #include "methodjit/nunbox/FrameEntry.h" namespace js { namespace mjit { enum TypeInfo { Type_Unknown }; +struct FrameAddress : JSC::MacroAssembler::Address +{ + FrameAddress(int32 offset) + : Address(JSC::MacroAssembler::stackPointerRegister, offset) + { } +}; + class FrameState { typedef JSC::MacroAssembler::RegisterID RegisterID; typedef JSC::MacroAssembler::Address Address; typedef JSC::MacroAssembler MacroAssembler; struct RegState { enum ValuePart { @@ -66,17 +73,17 @@ class FrameState uint32 index; ValuePart part; bool spillable; bool tracked; }; public: - FrameState(JSContext *cx, JSScript *script, MacroAssembler &masm) + FrameState(JSContext *cx, JSScript *script, Assembler &masm) : cx(cx), script(script), masm(masm), base(NULL) { } ~FrameState(); #if defined(JS_CPU_X86) || defined(JS_CPU_X64) static const RegisterID FpReg = JSC::X86Registers::ebx; #elif defined(JS_CPU_ARM) static const RegisterID FpReg = JSC::X86Registers::r11; @@ -181,26 +188,31 @@ class FrameState sp = spBase + newDepth; if (oldDepth <= newDepth) return; memset(spBase, 0, sizeof(FrameEntry) * (newDepth - oldDepth)); } void flush(); void assertValidRegisterState(); + void sync(Assembler &masm) const; + void restoreTempRegs(Assembler &masm) const; private: + void syncType(FrameEntry *fe, Assembler &masm) const; + void syncData(FrameEntry *fe, Assembler &masm) const; + void syncRegister(Assembler &masm, RegisterID reg, const RegState &state) const; void evictSomething(); void invalidate(FrameEntry *fe); RegisterID getDataReg(FrameEntry *vi, FrameEntry *backing); private: JSContext *cx; JSScript *script; - MacroAssembler &masm; + Assembler &masm; FrameEntry *base; FrameEntry *locals; FrameEntry *args; FrameEntry *sp; Registers regalloc; RegState regstate[MacroAssembler::TotalRegisters]; };