From 28beac255bba1655eeb4595f7c4f77222d3b5b29 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Thu, 22 Sep 2011 17:35:25 +0100 Subject: [PATCH] Bug 685315 - Remove the GETGLOBAL opcode; r=dvander This was a nice and simple way to get a perf boost in the interpreter and JM, but JSOP_GETGNAME has the same information and more. TI doesn't need it, JM technically doesn't, and IM won't either. We can just do a normal property lookup during compilation. --- js/src/jsemit.cpp | 15 +++--------- js/src/jsinfer.cpp | 17 ++----------- js/src/jsinterp.cpp | 15 ++---------- js/src/jsopcode.cpp | 16 ------------ js/src/jsopcode.h | 1 - js/src/jsopcode.tbl | 4 +-- js/src/jsscript.h | 12 --------- js/src/jstracer.cpp | 18 ++------------ js/src/jsxdrapi.h | 2 +- js/src/methodjit/Compiler.cpp | 39 ------------------------------ js/src/methodjit/Compiler.h | 1 - js/src/methodjit/InvokeHelpers.cpp | 2 -- 12 files changed, 13 insertions(+), 129 deletions(-) diff --git a/js/src/jsemit.cpp b/js/src/jsemit.cpp index 99b30a0bb475..fb3ff20d3659 100644 --- a/js/src/jsemit.cpp +++ b/js/src/jsemit.cpp @@ -2268,10 +2268,9 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) * by a local variable, and not mutating the variable, try and * optimize to a fast, unguarded global access. */ - if (!BindKnownGlobal(cx, cg, dn, pn, atom)) - return JS_FALSE; if (!pn->pn_cookie.isFree()) { - pn->setOp(JSOP_GETGLOBAL); + pn->setOp(JSOP_GETGNAME); + pn->pn_dflags |= PND_BOUND; return JS_TRUE; } } @@ -2279,7 +2278,7 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) /* * The locally stored cookie here should really come from |pn|, not * |dn|. For example, we could have a SETGNAME op's lexdef be a - * GETGLOBAL op, and their cookies have very different meanings. As + * GETGNAME op, and their cookies have very different meanings. As * a workaround, just make the cookie free. */ cookie.makeFree(); @@ -2772,9 +2771,6 @@ EmitNameOp(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn, case JSOP_GETGNAME: op = JSOP_CALLGNAME; break; - case JSOP_GETGLOBAL: - op = JSOP_CALLGLOBAL; - break; case JSOP_GETARG: op = JSOP_CALLARG; break; @@ -4659,10 +4655,7 @@ EmitAssignment(JSContext *cx, JSCodeGenerator *cg, JSParseNode *lhs, JSOp op, JS } else if (lhs->isOp(JSOP_SETGNAME)) { if (!BindGlobal(cx, cg, lhs, lhs->pn_atom)) return false; - if (lhs->pn_cookie.isFree()) - EmitAtomOp(cx, lhs, JSOP_GETGNAME, cg); - else - EMIT_UINT16_IMM_OP(JSOP_GETGLOBAL, lhs->pn_cookie.asInteger()); + EmitAtomOp(cx, lhs, JSOP_GETGNAME, cg); } else { EMIT_UINT16_IMM_OP(lhs->isOp(JSOP_SETARG) ? JSOP_GETARG : JSOP_GETLOCAL, atomIndex); } diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 49959af418be..e79d8ad5ea97 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -1974,13 +1974,6 @@ GetAtomId(JSContext *cx, JSScript *script, const jsbytecode *pc, unsigned offset return MakeTypeId(cx, ATOM_TO_JSID(script->getAtom(index))); } -static inline jsid -GetGlobalId(JSContext *cx, JSScript *script, const jsbytecode *pc) -{ - unsigned index = GET_SLOTNO(pc); - return MakeTypeId(cx, ATOM_TO_JSID(script->getGlobalAtom(index))); -} - static inline JSObject * GetScriptObject(JSContext *cx, JSScript *script, const jsbytecode *pc, unsigned offset) { @@ -3463,15 +3456,9 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, break; } - case JSOP_GETGLOBAL: - case JSOP_CALLGLOBAL: case JSOP_GETGNAME: case JSOP_CALLGNAME: { - jsid id; - if (op == JSOP_GETGLOBAL || op == JSOP_CALLGLOBAL) - id = GetGlobalId(cx, script, pc); - else - id = GetAtomId(cx, script, pc, 0); + jsid id = GetAtomId(cx, script, pc, 0); TypeSet *seen = bytecodeTypes(pc); seen->addSubset(cx, &pushed[0]); @@ -3491,7 +3478,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, /* Handle as a property access. */ PropertyAccess(cx, script, pc, script->global()->getType(cx), false, seen, id); - if (op == JSOP_CALLGLOBAL || op == JSOP_CALLGNAME) { + if (op == JSOP_CALLGNAME) { pushed[1].addType(cx, Type::UnknownType()); pushed[0].addPropagateThis(cx, script, pc, Type::UnknownType()); } diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 2bc9d178584d..a5d5de71dd87 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -4579,19 +4579,8 @@ BEGIN_CASE(JSOP_CALLFCSLOT) } END_CASE(JSOP_GETFCSLOT) -BEGIN_CASE(JSOP_GETGLOBAL) -BEGIN_CASE(JSOP_CALLGLOBAL) -{ - uint32 slot = GET_SLOTNO(regs.pc); - slot = script->getGlobalSlot(slot); - JSObject *obj = regs.fp()->scopeChain().getGlobal(); - JS_ASSERT(obj->containsSlot(slot)); - PUSH_COPY(obj->getSlot(slot)); - TypeScript::Monitor(cx, script, regs.pc, regs.sp[-1]); - if (op == JSOP_CALLGLOBAL) - PUSH_UNDEFINED(); -} -END_CASE(JSOP_GETGLOBAL) +BEGIN_CASE(JSOP_UNUSED0) +BEGIN_CASE(JSOP_UNUSED1) BEGIN_CASE(JSOP_DEFCONST) BEGIN_CASE(JSOP_DEFVAR) diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 0fcd890bc608..18a4975fe5b3 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -545,17 +545,6 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, } break; - case JOF_GLOBAL: - atom = script->getGlobalAtom(GET_SLOTNO(pc)); - v = STRING_TO_JSVAL(atom); - { - JSAutoByteString bytes; - if (!ToDisassemblySource(cx, v, &bytes)) - return 0; - Sprint(sp, " %s", bytes.ptr()); - } - break; - case JOF_UINT16PAIR: i = (jsint)GET_UINT16(pc); Sprint(sp, " %d", i); @@ -4016,11 +4005,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) #endif goto do_name; - case JSOP_CALLGLOBAL: - case JSOP_GETGLOBAL: - atom = jp->script->getGlobalAtom(GET_SLOTNO(pc)); - goto do_name; - case JSOP_CALLNAME: case JSOP_NAME: case JSOP_GETGNAME: diff --git a/js/src/jsopcode.h b/js/src/jsopcode.h index 15287c3531aa..89107d97dbe9 100644 --- a/js/src/jsopcode.h +++ b/js/src/jsopcode.h @@ -96,7 +96,6 @@ typedef enum JSOp { #define JOF_INT8 18 /* int8 immediate operand */ #define JOF_ATOMOBJECT 19 /* uint16 constant index + object index */ #define JOF_UINT16PAIR 20 /* pair of uint16 immediates */ -#define JOF_GLOBAL 21 /* uint16 global array index */ #define JOF_TYPEMASK 0x001f /* mask for above immediate types */ #define JOF_NAME (1U<<5) /* name operation */ diff --git a/js/src/jsopcode.tbl b/js/src/jsopcode.tbl index a6320ac7bfb4..8df70f012dfe 100644 --- a/js/src/jsopcode.tbl +++ b/js/src/jsopcode.tbl @@ -275,8 +275,8 @@ OPDEF(JSOP_LOCALDEC, 104,"localdec", NULL, 3, 0, 1, 15, JOF_LOCAL| OPDEF(JSOP_IMACOP, 105,"imacop", NULL, 1, 0, 0, 0, JOF_BYTE) /* Static binding for globals. */ -OPDEF(JSOP_GETGLOBAL, 106,"getglobal", NULL, 3, 0, 1, 19, JOF_GLOBAL|JOF_NAME|JOF_TYPESET) -OPDEF(JSOP_CALLGLOBAL,107,"callglobal", NULL, 3, 0, 2, 19, JOF_GLOBAL|JOF_NAME|JOF_TYPESET|JOF_CALLOP) +OPDEF(JSOP_UNUSED0, 106,"unused0", NULL, 3, 0, 1, 19, JOF_BYTE) +OPDEF(JSOP_UNUSED1, 107,"unused1", NULL, 3, 0, 2, 19, JOF_BYTE) /* Like JSOP_FUNAPPLY but for f.call instead of f.apply. */ OPDEF(JSOP_FUNCALL, 108,"funcall", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE|JOF_TYPESET) diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 39a66f8b4b68..595cc3e06cb9 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -747,18 +747,6 @@ struct JSScript : public js::gc::Cell { return arr->vector[index]; } - uint32 getGlobalSlot(size_t index) { - js::GlobalSlotArray *arr = globals(); - JS_ASSERT(index < arr->length); - return arr->vector[index].slot; - } - - JSAtom *getGlobalAtom(size_t index) { - js::GlobalSlotArray *arr = globals(); - JS_ASSERT(index < arr->length); - return getAtom(arr->vector[index].atomIndex); - } - JSVersion getVersion() const { return JSVersion(version); } diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index a258f7967452..2c575b203afa 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -16361,26 +16361,12 @@ TraceRecorder::record_JSOP_SHARPINIT() } JS_REQUIRES_STACK AbortableRecordingStatus -TraceRecorder::record_JSOP_GETGLOBAL() -{ - uint32 slot = cx->fp()->script()->getGlobalSlot(GET_SLOTNO(cx->regs().pc)); - if (!lazilyImportGlobalSlot(slot)) - RETURN_STOP_A("lazy import of global slot failed"); - - stack(0, get(&globalObj->getSlotRef(slot))); +TraceRecorder::record_JSOP_UNUSED0() { return ARECORD_CONTINUE; } JS_REQUIRES_STACK AbortableRecordingStatus -TraceRecorder::record_JSOP_CALLGLOBAL() -{ - uint32 slot = cx->fp()->script()->getGlobalSlot(GET_SLOTNO(cx->regs().pc)); - if (!lazilyImportGlobalSlot(slot)) - RETURN_STOP_A("lazy import of global slot failed"); - - const Value &v = globalObj->getSlot(slot); - stack(0, get(&v)); - stack(1, w.immiUndefined()); +TraceRecorder::record_JSOP_UNUSED1() { return ARECORD_CONTINUE; } diff --git a/js/src/jsxdrapi.h b/js/src/jsxdrapi.h index c3b937508241..61984055f453 100644 --- a/js/src/jsxdrapi.h +++ b/js/src/jsxdrapi.h @@ -222,7 +222,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id); * before deserialization of bytecode. If the saved version does not match * the current version, abort deserialization and invalidate the file. */ -#define JSXDR_BYTECODE_VERSION (0xb973c0de - 94) +#define JSXDR_BYTECODE_VERSION (0xb973c0de - 95) /* * Library-private functions. diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index abdee928b2e7..34ddcf2233fb 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -2758,13 +2758,6 @@ mjit::Compiler::generateMethod() INLINE_STUBCALL(stubs::UnbrandThis, REJOIN_FALLTHROUGH); END_CASE(JSOP_UNBRANDTHIS) - BEGIN_CASE(JSOP_GETGLOBAL) - BEGIN_CASE(JSOP_CALLGLOBAL) - jsop_getglobal(GET_SLOTNO(PC)); - if (op == JSOP_CALLGLOBAL) - frame.push(UndefinedValue()); - END_CASE(JSOP_GETGLOBAL) - default: /* Sorry, this opcode isn't implemented yet. */ #ifdef JS_METHODJIT_SPEW @@ -2897,38 +2890,6 @@ mjit::Compiler::jumpInScript(Jump j, jsbytecode *pc) return branchPatches.append(BranchPatch(j, pc, a->inlineIndex)); } -void -mjit::Compiler::jsop_getglobal(uint32 index) -{ - JS_ASSERT(globalObj); - uint32 slot = script->getGlobalSlot(index); - - JSObject *singleton = pushedSingleton(0); - if (singleton && !hasTypeBarriers(PC) && !globalObj->getSlot(slot).isUndefined()) { - frame.push(ObjectValue(*singleton)); - return; - } - - if (cx->typeInferenceEnabled() && globalObj->isGlobal() && - !globalObj->getType(cx)->unknownProperties()) { - Value *value = &globalObj->getSlotRef(slot); - if (!value->isUndefined()) { - watchGlobalReallocation(); - RegisterID reg = frame.allocReg(); - masm.move(ImmPtr(value), reg); - - BarrierState barrier = pushAddressMaybeBarrier(Address(reg), knownPushedType(0), true); - finishBarrier(barrier, REJOIN_GETTER, 0); - return; - } - } - - RegisterID reg = frame.allocReg(); - Address address = masm.objSlotRef(globalObj, reg, slot); - BarrierState barrier = pushAddressMaybeBarrier(address, knownPushedType(0), true); - finishBarrier(barrier, REJOIN_GETTER, 0); -} - void mjit::Compiler::emitFinalReturn(Assembler &masm) { diff --git a/js/src/methodjit/Compiler.h b/js/src/methodjit/Compiler.h index 13c13c2513df..f7efaff6a11e 100644 --- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -615,7 +615,6 @@ class Compiler : public BaseCompiler bool finishLoop(jsbytecode *head); void jsop_bindname(JSAtom *atom, bool usePropCache); void jsop_setglobal(uint32 index); - void jsop_getglobal(uint32 index); void jsop_getprop_slow(JSAtom *atom, bool usePropCache = true); void jsop_getarg(uint32 slot); void jsop_setarg(uint32 slot, bool popped); diff --git a/js/src/methodjit/InvokeHelpers.cpp b/js/src/methodjit/InvokeHelpers.cpp index 66e252704646..b8531678061c 100644 --- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -1475,7 +1475,6 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM switch (op) { case JSOP_NAME: case JSOP_GETGNAME: - case JSOP_GETGLOBAL: case JSOP_GETFCSLOT: case JSOP_GETPROP: case JSOP_GETXPROP: @@ -1491,7 +1490,6 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM f.regs.pc = nextpc; break; - case JSOP_CALLGLOBAL: case JSOP_CALLFCSLOT: /* |this| is always undefined for CALLGLOBAL/CALLFCSLOT. */ nextsp[-1].setUndefined();