From 2ea8bbcb09ebfc280a2391b17ad64fcf3a1802f9 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Tue, 2 Aug 2011 11:02:09 -0700 Subject: [PATCH] Bug 631998 - CALLPROP fix (r=dmandelin) --- js/src/jsscript.cpp | 4 ++++ js/src/methodjit/Compiler.cpp | 17 ++++++++++++++++- js/src/methodjit/Compiler.h | 1 + js/src/methodjit/MethodJIT.cpp | 35 ++++++++++++++++++++++++++++------ js/src/methodjit/MethodJIT.h | 7 +++++++ 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 528f1c754d4b..2a54d36aebbc 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1472,6 +1472,10 @@ js_TraceScript(JSTracer *trc, JSScript *script, JSObject *owner) js_MarkScriptFilename(script->filename); script->bindings.trace(trc); + +#ifdef JS_METHODJIT + mjit::TraceScript(trc, script); +#endif } JSObject * diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index fee690b5c87c..5b7415e9b0ae 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -113,6 +113,7 @@ mjit::Compiler::Compiler(JSContext *cx, StackFrame *fp) doubleList(CompilerAllocPolicy(cx, *thisFromCtor())), jumpTables(CompilerAllocPolicy(cx, *thisFromCtor())), jumpTableOffsets(CompilerAllocPolicy(cx, *thisFromCtor())), + rootedObjects(CompilerAllocPolicy(cx, *thisFromCtor())), stubcc(cx, *thisFromCtor(), frame, script), debugMode_(cx->compartment->debugMode), #if defined JS_TRACER @@ -457,7 +458,8 @@ mjit::Compiler::finishThisUp(JITScript **jitp) sizeof(ic::GetElementIC) * getElemICs.length() + sizeof(ic::SetElementIC) * setElemICs.length() + #endif - sizeof(CallSite) * callSites.length(); + sizeof(CallSite) * callSites.length() + + sizeof(JSObject *) * rootedObjects.length(); uint8 *cursor = (uint8 *)cx->calloc_(dataSize); if (!cursor) { @@ -820,6 +822,13 @@ mjit::Compiler::finishThisUp(JITScript **jitp) to.initialize(codeOffset, from.pc - script->code, from.id); } + /* Build the list of objects rooted by the script. */ + JSObject **jitRooted = (JSObject **)cursor; + jit->nRootedObjects = rootedObjects.length(); + cursor += sizeof(JSObject *) * jit->nRootedObjects; + for (size_t i = 0; i < jit->nRootedObjects; i++) + jitRooted[i] = rootedObjects[i]; + JS_ASSERT(size_t(cursor - (uint8*)jit) == dataSize); *jitp = jit; @@ -3241,6 +3250,12 @@ mjit::Compiler::jsop_callprop_str(JSAtom *atom) if (!js_GetClassPrototype(cx, &fp->scopeChain(), JSProto_String, &obj)) return false; + /* + * Root the proto, since JS_ClearScope might overwrite the global object's + * copy. + */ + rootedObjects.append(obj); + /* Force into a register because getprop won't expect a constant. */ RegisterID reg = frame.allocReg(); diff --git a/js/src/methodjit/Compiler.h b/js/src/methodjit/Compiler.h index 96a34210df57..093051b6895a 100644 --- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -358,6 +358,7 @@ class Compiler : public BaseCompiler js::Vector doubleList; js::Vector jumpTables; js::Vector jumpTableOffsets; + js::Vector rootedObjects; StubCompiler stubcc; Label invokeLabel; Label arityLabel; diff --git a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp index 758bffe343ad..7df63ba4b86f 100644 --- a/js/src/methodjit/MethodJIT.cpp +++ b/js/src/methodjit/MethodJIT.cpp @@ -40,6 +40,7 @@ #include "Logging.h" #include "assembler/jit/ExecutableAllocator.h" #include "jstracer.h" +#include "jsgcmark.h" #include "BaseAssembler.h" #include "Compiler.h" #include "MonoIC.h" @@ -752,7 +753,7 @@ JITScript::nmap() const char * JITScript::nmapSectionLimit() const { - return (char *)nmap() + sizeof(NativeMapEntry) * nNmapPairs; + return (char *)&nmap()[nNmapPairs]; } #ifdef JS_MONOIC @@ -772,26 +773,25 @@ JITScript::setGlobalNames() const ic::CallICInfo * JITScript::callICs() const { - return (ic::CallICInfo *)((char *)setGlobalNames() + - sizeof(ic::SetGlobalNameIC) * nSetGlobalNames); + return (ic::CallICInfo *)&setGlobalNames()[nSetGlobalNames]; } ic::EqualityICInfo * JITScript::equalityICs() const { - return (ic::EqualityICInfo *)((char *)callICs() + sizeof(ic::CallICInfo) * nCallICs); + return (ic::EqualityICInfo *)&callICs()[nCallICs]; } ic::TraceICInfo * JITScript::traceICs() const { - return (ic::TraceICInfo *)((char *)equalityICs() + sizeof(ic::EqualityICInfo) * nEqualityICs); + return (ic::TraceICInfo *)&equalityICs()[nEqualityICs]; } char * JITScript::monoICSectionsLimit() const { - return (char *)traceICs() + sizeof(ic::TraceICInfo) * nTraceICs; + return (char *)&traceICs()[nTraceICs]; } #else // JS_MONOIC char * @@ -839,6 +839,12 @@ JITScript::callSites() const return (js::mjit::CallSite *)polyICSectionsLimit(); } +JSObject ** +JITScript::rootedObjects() const +{ + return (JSObject **)&callSites()[nCallSites]; +} + template static inline void Destroy(T &t) { @@ -875,6 +881,13 @@ mjit::JITScript::~JITScript() #endif } +void +mjit::JITScript::trace(JSTracer *trc) +{ + for (uint32 i = 0; i < nRootedObjects; ++i) + MarkObject(trc, *rootedObjects()[i], "mjit rooted object"); +} + size_t JSScript::jitDataSize() { @@ -930,6 +943,16 @@ mjit::ReleaseScriptCode(JSContext *cx, JSScript *script) } } +void +mjit::TraceScript(JSTracer *trc, JSScript *script) +{ + if (JITScript *jit = script->jitNormal) + jit->trace(trc); + + if (JITScript *jit = script->jitCtor) + jit->trace(trc); +} + #ifdef JS_METHODJIT_PROFILE_STUBS void JS_FASTCALL mjit::ProfileStubCall(VMFrame &f) diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h index 374565369732..fb5d5fceba60 100644 --- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -382,6 +382,7 @@ struct JITScript { uint32 nPICs; #endif uint32 nCallSites; + uint32 nRootedObjects; #ifdef JS_MONOIC // Additional ExecutablePools that IC stubs were generated into. @@ -403,6 +404,7 @@ struct JITScript { ic::PICInfo *pics() const; #endif js::mjit::CallSite *callSites() const; + JSObject **rootedObjects() const; ~JITScript(); @@ -417,6 +419,8 @@ struct JITScript { void purgeMICs(); void purgePICs(); + void trace(JSTracer *trc); + size_t scriptDataSize(); jsbytecode *nativeToPC(void *returnAddress) const; @@ -456,6 +460,9 @@ TryCompile(JSContext *cx, StackFrame *fp); void ReleaseScriptCode(JSContext *cx, JSScript *script); +void +TraceScript(JSTracer *trc, JSScript *script); + struct CallSite { uint32 codeOffset;