From d3435e89d8d5acbe23d9d189e46caf35320ba9ea Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Fri, 9 Sep 2011 21:55:57 +0200 Subject: [PATCH] [INFER] Always maintain a synced interpreter stack for method JIT stub calls, bug 685358. --- js/src/jscompartment.cpp | 77 +++------------ js/src/jscompartment.h | 2 +- js/src/jsgc.cpp | 28 ++---- js/src/jsgcmark.cpp | 7 -- js/src/methodjit/Compiler.cpp | 15 --- js/src/methodjit/Compiler.h | 1 - js/src/methodjit/FrameState.cpp | 14 +-- js/src/methodjit/MethodJIT.cpp | 25 +---- js/src/methodjit/MethodJIT.h | 7 -- js/src/methodjit/MonoIC.cpp | 163 -------------------------------- js/src/methodjit/MonoIC.h | 3 - js/src/methodjit/PolyIC.cpp | 52 ---------- js/src/methodjit/PolyIC.h | 1 - 13 files changed, 24 insertions(+), 371 deletions(-) diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 51a407988d4..2ab0c9c78de 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -506,7 +506,7 @@ JSCompartment::markTypes(JSTracer *trc) } void -JSCompartment::sweep(JSContext *cx, uint32 releaseInterval) +JSCompartment::sweep(JSContext *cx, bool releaseTypes) { /* Remove dead wrappers from the table. */ for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) { @@ -545,49 +545,8 @@ JSCompartment::sweep(JSContext *cx, uint32 releaseInterval) traceMonitor()->sweep(cx); #endif -# if defined JS_METHODJIT && defined JS_POLYIC - /* - * Purge all PICs in the compartment. These can reference type data and - * need to know which types are pending collection. - */ - for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); - if (script->hasJITCode()) - mjit::ic::PurgePICs(cx, script); - } -# endif - - bool discardScripts = !active && (releaseInterval != 0 || hasDebugModeCodeToDrop); - -#if defined JS_METHODJIT && defined JS_MONOIC - - /* - * The release interval is the frequency with which we should try to destroy - * executable pools by releasing all JIT code in them, zero to never destroy pools. - * Initialize counter so that the first pool will be destroyed, and eventually drive - * the amount of JIT code in never-used compartments to zero. Don't discard anything - * for compartments which currently have active stack frames. - */ - uint32 counter = 1; - if (discardScripts) - hasDebugModeCodeToDrop = false; - - for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); - if (script->hasJITCode()) { - mjit::ic::SweepCallICs(cx, script, discardScripts); - if (discardScripts) { - ScriptTryDestroyCode(cx, script, true, releaseInterval, counter); - ScriptTryDestroyCode(cx, script, false, releaseInterval, counter); - } - } - } - -#endif - #ifdef JS_METHODJIT - if (types.inferenceEnabled) - mjit::ClearAllFrames(this); + mjit::ClearAllFrames(this); #endif if (activeAnalysis) { @@ -597,11 +556,9 @@ JSCompartment::sweep(JSContext *cx, uint32 releaseInterval) * GC then shape numbers baked into the code may change. */ #ifdef JS_METHODJIT - if (types.inferenceEnabled) { - for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); - mjit::ReleaseScriptCode(cx, script); - } + for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { + JSScript *script = i.get(); + mjit::ReleaseScriptCode(cx, script); } #endif } else { @@ -618,17 +575,19 @@ JSCompartment::sweep(JSContext *cx, uint32 releaseInterval) * enabled in the compartment. */ if (types.inferenceEnabled) { + if (active) + releaseTypes = false; for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get(); if (script->types) { types::TypeScript::Sweep(cx, script); /* - * On each 1/8 lifetime, release observed types for all scripts. - * This is always safe to do when there are no frames for the - * compartment on the stack. + * Periodically release observed types for all scripts. + * This is always safe to do when there are no frames for + * the compartment on the stack. */ - if (discardScripts) { + if (releaseTypes) { script->types->destroy(); script->types = NULL; script->typesPurged = true; @@ -684,20 +643,6 @@ JSCompartment::purge(JSContext *cx) if (hasTraceMonitor()) traceMonitor()->needFlush = JS_TRUE; #endif - -#if defined JS_METHODJIT && defined JS_MONOIC - /* - * MICs do not refer to data which can be GC'ed and do not generate stubs - * which might need to be discarded, but are sensitive to shape regeneration. - */ - if (cx->runtime->gcRegenShapes) { - for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); - if (script->hasJITCode()) - mjit::ic::PurgeMICs(cx, script); - } - } -#endif } MathCache * diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index cfd240ac396..32398e42616 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -532,7 +532,7 @@ struct JS_FRIEND_API(JSCompartment) { bool wrap(JSContext *cx, js::AutoIdVector &props); void markTypes(JSTracer *trc); - void sweep(JSContext *cx, uint32 releaseInterval); + void sweep(JSContext *cx, bool releaseTypes); void purge(JSContext *cx); void setGCLastBytes(size_t lastBytes, JSGCInvocationKind gckind); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 57ac9b0f38e..3d9ca3fa629 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -646,12 +646,8 @@ js_GCThingIsMarked(void *thing, uintN color = BLACK) return reinterpret_cast(thing)->isMarked(color); } -/* - * 1/8 life for JIT code. After this number of microseconds have passed, 1/8 of all - * JIT code is discarded in inactive compartments, regardless of how often that - * code runs. - */ -static const int64 JIT_SCRIPT_EIGHTH_LIFETIME = 60 * 1000 * 1000; +/* Lifetime for type sets attached to scripts containing observed types. */ +static const int64 JIT_SCRIPT_RELEASE_TYPES_INTERVAL = 60 * 1000 * 1000; JSBool js_InitGC(JSRuntime *rt, uint32 maxbytes) @@ -693,7 +689,7 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes) */ rt->setGCLastBytes(8192, GC_NORMAL); - rt->gcJitReleaseTime = PRMJ_Now() + JIT_SCRIPT_EIGHTH_LIFETIME; + rt->gcJitReleaseTime = PRMJ_Now() + JIT_SCRIPT_RELEASE_TYPES_INTERVAL; return true; } @@ -2127,20 +2123,12 @@ static void SweepCrossCompartmentWrappers(JSContext *cx) { JSRuntime *rt = cx->runtime; - /* - * Figure out how much JIT code should be released from inactive compartments. - * If multiple eighth-lives have passed, compound the release interval linearly; - * if enough time has passed, all inactive JIT code will be released. - */ - uint32 releaseInterval = 0; + + bool releaseTypes = false; int64 now = PRMJ_Now(); if (now >= rt->gcJitReleaseTime) { - releaseInterval = 8; - while (now >= rt->gcJitReleaseTime) { - if (--releaseInterval == 1) - rt->gcJitReleaseTime = now; - rt->gcJitReleaseTime += JIT_SCRIPT_EIGHTH_LIFETIME; - } + releaseTypes = true; + rt->gcJitReleaseTime = now + JIT_SCRIPT_RELEASE_TYPES_INTERVAL; } /* @@ -2151,7 +2139,7 @@ SweepCrossCompartmentWrappers(JSContext *cx) * (4) Sweep the method JIT ICs and release infrequently used JIT code. */ for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) - (*c)->sweep(cx, releaseInterval); + (*c)->sweep(cx, releaseTypes); } static void diff --git a/js/src/jsgcmark.cpp b/js/src/jsgcmark.cpp index ef7acfaf0ca..c118112205b 100644 --- a/js/src/jsgcmark.cpp +++ b/js/src/jsgcmark.cpp @@ -859,13 +859,6 @@ MarkChildren(JSTracer *trc, JSScript *script) if (script->types) script->types->trace(trc); - -#ifdef JS_METHODJIT - if (script->jitNormal) - script->jitNormal->trace(trc); - if (script->jitCtor) - script->jitCtor->trace(trc); -#endif } void diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index ee216056ad7..741046dafdc 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -122,7 +122,6 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript, bool isConstructi jumpTables(CompilerAllocPolicy(cx, *thisFromCtor())), jumpTableOffsets(CompilerAllocPolicy(cx, *thisFromCtor())), loopEntries(CompilerAllocPolicy(cx, *thisFromCtor())), - rootedObjects(CompilerAllocPolicy(cx, *thisFromCtor())), stubcc(cx, *thisFromCtor(), frame), debugMode_(cx->compartment->debugMode()), #if defined JS_TRACER @@ -942,7 +941,6 @@ mjit::Compiler::finishThisUp(JITScript **jitp) sizeof(NativeMapEntry) * nNmapLive + sizeof(InlineFrame) * inlineFrames.length() + sizeof(CallSite) * callSites.length() + - sizeof(JSObject *) * rootedObjects.length() + #if defined JS_MONOIC sizeof(ic::GetGlobalNameIC) * getGlobalNames.length() + sizeof(ic::SetGlobalNameIC) * setGlobalNames.length() + @@ -1074,13 +1072,6 @@ mjit::Compiler::finishThisUp(JITScript **jitp) stubCode.patch(from.loopPatch.codePatch, result + codeOffset); } - /* 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]; - #if defined JS_MONOIC JS_INIT_CLIST(&jit->callers); @@ -4661,12 +4652,6 @@ mjit::Compiler::jsop_callprop_str(JSAtom *atom) if (!js_GetClassPrototype(cx, globalObj, 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 c59cd863099..d49cc9c965a 100644 --- a/js/src/methodjit/Compiler.h +++ b/js/src/methodjit/Compiler.h @@ -455,7 +455,6 @@ class Compiler : public BaseCompiler js::Vector jumpTables; js::Vector jumpTableOffsets; js::Vector loopEntries; - js::Vector rootedObjects; StubCompiler stubcc; Label invokeLabel; Label arityLabel; diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index 372b5affcf8..1a83e3f8b53 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -1324,11 +1324,7 @@ FrameState::sync(Assembler &masm, Uses uses) const Registers avail(freeRegs.freeMask & Registers::AvailRegs); Registers temp(Registers::TempAnyRegs); - FrameEntry *bottom = (cx->typeInferenceEnabled() || cx->compartment->debugMode()) - ? entries - : a->sp - uses.nuses; - - for (FrameEntry *fe = a->sp - 1; fe >= bottom; fe--) { + for (FrameEntry *fe = a->sp - 1; fe >= entries; fe--) { if (!fe->isTracked()) continue; @@ -1378,7 +1374,7 @@ FrameState::sync(Assembler &masm, Uses uses) const /* Fall back to a slower sync algorithm if load required. */ if ((!fe->type.synced() && backing->type.inMemory()) || (!fe->data.synced() && backing->data.inMemory())) { - syncFancy(masm, avail, fe, bottom); + syncFancy(masm, avail, fe, entries); return; } #endif @@ -1459,11 +1455,7 @@ FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore) uint32 maxvisits = tracker.nentries; - FrameEntry *bottom = (cx->typeInferenceEnabled() || cx->compartment->debugMode()) - ? entries - : a->sp - uses.nuses; - - for (FrameEntry *fe = a->sp - 1; fe >= bottom && maxvisits; fe--) { + for (FrameEntry *fe = a->sp - 1; fe >= entries && maxvisits; fe--) { if (!fe->isTracked()) continue; diff --git a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp index 0649fe17f2c..40d9e5b0d80 100644 --- a/js/src/methodjit/MethodJIT.cpp +++ b/js/src/methodjit/MethodJIT.cpp @@ -990,16 +990,10 @@ JITScript::callSites() const return (js::mjit::CallSite *)&inlineFrames()[nInlineFrames]; } -JSObject ** -JITScript::rootedObjects() const -{ - return (JSObject **)&callSites()[nCallSites]; -} - char * JITScript::commonSectionLimit() const { - return (char *)&rootedObjects()[nRootedObjects]; + return (char *)&callSites()[nCallSites]; } #ifdef JS_MONOIC @@ -1164,7 +1158,6 @@ mjit::JITScript::scriptDataSize(JSUsableSizeFun usf) sizeof(NativeMapEntry) * nNmapPairs + sizeof(InlineFrame) * nInlineFrames + sizeof(CallSite) * nCallSites + - sizeof(JSObject *) * nRootedObjects + #if defined JS_MONOIC sizeof(ic::GetGlobalNameIC) * nGetGlobalNames + sizeof(ic::SetGlobalNameIC) * nSetGlobalNames + @@ -1304,20 +1297,4 @@ mjit::NativeToPC(JITScript *jit, void *ncode, mjit::CallSite **pinline) return jit->nativeToPC(ncode, pinline); } -void -JITScript::trace(JSTracer *trc) -{ - /* - * MICs and PICs attached to the JITScript are weak references, and either - * entirely purged or selectively purged on each GC. We do, however, need - * to maintain references to any scripts whose code was inlined into this. - */ - InlineFrame *inlineFrames_ = inlineFrames(); - for (unsigned i = 0; i < nInlineFrames; i++) - MarkObject(trc, *inlineFrames_[i].fun, "jitscript_fun"); - - for (uint32 i = 0; i < nRootedObjects; ++i) - MarkObject(trc, *rootedObjects()[i], "mjit rooted object"); -} - /* static */ const double mjit::Assembler::oneDouble = 1.0; diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h index bc356f3fecc..e3e22dc6a25 100644 --- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -605,7 +605,6 @@ struct JITScript { bool singleStepMode:1; /* compiled in "single step mode" */ uint32 nInlineFrames; uint32 nCallSites; - uint32 nRootedObjects; #ifdef JS_MONOIC uint32 nGetGlobalNames; uint32 nSetGlobalNames; @@ -643,7 +642,6 @@ struct JITScript { NativeMapEntry *nmap() const; js::mjit::InlineFrame *inlineFrames() const; js::mjit::CallSite *callSites() const; - JSObject **rootedObjects() const; #ifdef JS_MONOIC ic::GetGlobalNameIC *getGlobalNames() const; ic::SetGlobalNameIC *setGlobalNames() const; @@ -666,11 +664,6 @@ struct JITScript { } void nukeScriptDependentICs(); - void sweepCallICs(JSContext *cx, bool purgeAll); - void purgeMICs(); - void purgePICs(); - - void trace(JSTracer *trc); /* |usf| can be NULL here, in which case the fallback size computation will be used. */ size_t scriptDataSize(JSUsableSizeFun usf); diff --git a/js/src/methodjit/MonoIC.cpp b/js/src/methodjit/MonoIC.cpp index 1a4d11445da..89d41c945c0 100644 --- a/js/src/methodjit/MonoIC.cpp +++ b/js/src/methodjit/MonoIC.cpp @@ -1383,168 +1383,5 @@ JITScript::resetArgsCheck() repatch.relink(argsCheckJump, argsCheckStub); } -void -JITScript::purgeMICs() -{ - if (!nGetGlobalNames || !nSetGlobalNames) - return; - - Repatcher repatch(this); - - ic::GetGlobalNameIC *getGlobalNames_ = getGlobalNames(); - for (uint32 i = 0; i < nGetGlobalNames; i++) { - ic::GetGlobalNameIC &ic = getGlobalNames_[i]; - JSC::CodeLocationDataLabel32 label = ic.fastPathStart.dataLabel32AtOffset(ic.shapeOffset); - repatch.repatch(label, int(INVALID_SHAPE)); - } - - ic::SetGlobalNameIC *setGlobalNames_ = setGlobalNames(); - for (uint32 i = 0; i < nSetGlobalNames; i++) { - ic::SetGlobalNameIC &ic = setGlobalNames_[i]; - ic.patchInlineShapeGuard(repatch, int32(INVALID_SHAPE)); - - if (ic.hasExtraStub) { - Repatcher repatcher(ic.extraStub); - ic.patchExtraShapeGuard(repatcher, int32(INVALID_SHAPE)); - } - } -} - -void -ic::PurgeMICs(JSContext *cx, JSScript *script) -{ - /* MICs are purged during GC to handle changing shapes. */ - JS_ASSERT(cx->runtime->gcRegenShapes); - - if (script->jitNormal) - script->jitNormal->purgeMICs(); - if (script->jitCtor) - script->jitCtor->purgeMICs(); -} - -void -JITScript::nukeScriptDependentICs() -{ - if (!nCallICs) - return; - - Repatcher repatcher(this); - - ic::CallICInfo *callICs_ = callICs(); - for (uint32 i = 0; i < nCallICs; i++) { - ic::CallICInfo &ic = callICs_[i]; - if (!ic.fastGuardedObject) - continue; - repatcher.repatch(ic.funGuard, NULL); - repatcher.relink(ic.funJump, ic.slowPathStart); - ic.releasePool(CallICInfo::Pool_ClosureStub); - ic.fastGuardedObject = NULL; - ic.hasJsFunCheck = false; - } -} - -void -JITScript::sweepCallICs(JSContext *cx, bool purgeAll) -{ - Repatcher repatcher(this); - - /* - * If purgeAll is set, purge stubs in the script except those covered by PurgePICs - * (which is always called during GC). We want to remove references which can keep - * alive pools that we are trying to destroy (see JSCompartment::sweep). - */ - - ic::CallICInfo *callICs_ = callICs(); - for (uint32 i = 0; i < nCallICs; i++) { - ic::CallICInfo &ic = callICs_[i]; - - /* - * If the object is unreachable, we're guaranteed not to be currently - * executing a stub generated by a guard on that object. This lets us - * precisely GC call ICs while keeping the identity guard safe. - */ - bool fastFunDead = ic.fastGuardedObject && - (purgeAll || IsAboutToBeFinalized(cx, ic.fastGuardedObject)); - bool nativeDead = ic.fastGuardedNative && - (purgeAll || IsAboutToBeFinalized(cx, ic.fastGuardedNative)); - - /* - * There are three conditions where we need to relink: - * (1) purgeAll is true. - * (2) The native is dead, since it always has a stub. - * (3) The fastFun is dead *and* there is a closure stub. - * - * Note although both objects can be non-NULL, there can only be one - * of [closure, native] stub per call IC. - */ - if (purgeAll || nativeDead || (fastFunDead && ic.hasJsFunCheck)) { - repatcher.relink(ic.funJump, ic.slowPathStart); - ic.hit = false; - } - - if (fastFunDead) { - repatcher.repatch(ic.funGuard, NULL); - ic.purgeGuardedObject(); - } - - if (nativeDead) - ic.fastGuardedNative = NULL; - - if (purgeAll) { - ic.releasePool(CallICInfo::Pool_ScriptStub); - JSC::CodeLocationJump oolJump = ic.slowPathStart.jumpAtOffset(ic.oolJumpOffset); - JSC::CodeLocationLabel icCall = ic.slowPathStart.labelAtOffset(ic.icCallOffset); - repatcher.relink(oolJump, icCall); - } - } - - /* The arguments type check IC can refer to type objects which might be swept. */ - if (argsCheckPool) - resetArgsCheck(); - - if (purgeAll) { - /* Purge ICs generating stubs into execPools. */ - uint32 released = 0; - - ic::EqualityICInfo *equalityICs_ = equalityICs(); - for (uint32 i = 0; i < nEqualityICs; i++) { - ic::EqualityICInfo &ic = equalityICs_[i]; - if (!ic.generated) - continue; - - JSC::FunctionPtr fptr(JS_FUNC_TO_DATA_PTR(void *, ic::Equality)); - repatcher.relink(ic.stubCall, fptr); - repatcher.relink(ic.jumpToStub, ic.stubEntry); - - ic.generated = false; - released++; - } - - ic::SetGlobalNameIC *setGlobalNames_ = setGlobalNames(); - for (uint32 i = 0; i < nSetGlobalNames; i ++) { - ic::SetGlobalNameIC &ic = setGlobalNames_[i]; - if (!ic.hasExtraStub) - continue; - repatcher.relink(ic.fastPathStart.jumpAtOffset(ic.inlineShapeJump), ic.slowPathStart); - ic.hasExtraStub = false; - released++; - } - - JS_ASSERT(released == execPools.length()); - for (uint32 i = 0; i < released; i++) - execPools[i]->release(); - execPools.clear(); - } -} - -void -ic::SweepCallICs(JSContext *cx, JSScript *script, bool purgeAll) -{ - if (script->jitNormal) - script->jitNormal->sweepCallICs(cx, purgeAll); - if (script->jitCtor) - script->jitCtor->sweepCallICs(cx, purgeAll); -} - #endif /* JS_MONOIC */ diff --git a/js/src/methodjit/MonoIC.h b/js/src/methodjit/MonoIC.h index 0133055968d..982df545907 100644 --- a/js/src/methodjit/MonoIC.h +++ b/js/src/methodjit/MonoIC.h @@ -301,9 +301,6 @@ JSBool JS_FASTCALL SplatApplyArgs(VMFrame &f); void GenerateArgumentCheckStub(VMFrame &f); -void PurgeMICs(JSContext *cx, JSScript *script); -void SweepCallICs(JSContext *cx, JSScript *script, bool purgeAll); - } /* namespace ic */ } /* namespace mjit */ } /* namespace js */ diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index 3edec28fd5d..562cb4a32f4 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -3261,57 +3261,5 @@ ic::SetElement(VMFrame &f, ic::SetElementIC *ic) template void JS_FASTCALL ic::SetElement(VMFrame &f, SetElementIC *ic); template void JS_FASTCALL ic::SetElement(VMFrame &f, SetElementIC *ic); -void -JITScript::purgePICs() -{ - if (!nPICs && !nGetElems && !nSetElems) - return; - - Repatcher repatcher(this); - - ic::PICInfo *pics_ = pics(); - for (uint32 i = 0; i < nPICs; i++) { - ic::PICInfo &pic = pics_[i]; - switch (pic.kind) { - case ic::PICInfo::SET: - case ic::PICInfo::SETMETHOD: - SetPropCompiler::reset(repatcher, pic); - break; - case ic::PICInfo::NAME: - case ic::PICInfo::XNAME: - case ic::PICInfo::CALLNAME: - ScopeNameCompiler::reset(repatcher, pic); - break; - case ic::PICInfo::BIND: - BindNameCompiler::reset(repatcher, pic); - break; - case ic::PICInfo::CALL: /* fall-through */ - case ic::PICInfo::GET: - GetPropCompiler::reset(repatcher, pic); - break; - default: - JS_NOT_REACHED("Unhandled PIC kind"); - break; - } - pic.reset(); - } - - ic::GetElementIC *getElems_ = getElems(); - ic::SetElementIC *setElems_ = setElems(); - for (uint32 i = 0; i < nGetElems; i++) - getElems_[i].purge(repatcher); - for (uint32 i = 0; i < nSetElems; i++) - setElems_[i].purge(repatcher); -} - -void -ic::PurgePICs(JSContext *cx, JSScript *script) -{ - if (script->jitNormal) - script->jitNormal->purgePICs(); - if (script->jitCtor) - script->jitCtor->purgePICs(); -} - #endif /* JS_POLYIC */ diff --git a/js/src/methodjit/PolyIC.h b/js/src/methodjit/PolyIC.h index 9bf88a478a4..efb73a4de69 100644 --- a/js/src/methodjit/PolyIC.h +++ b/js/src/methodjit/PolyIC.h @@ -554,7 +554,6 @@ struct PICInfo : public BasePolyIC { }; #ifdef JS_POLYIC -void PurgePICs(JSContext *cx, JSScript *script); void JS_FASTCALL GetProp(VMFrame &f, ic::PICInfo *); void JS_FASTCALL GetPropNoCache(VMFrame &f, ic::PICInfo *); void JS_FASTCALL SetProp(VMFrame &f, ic::PICInfo *);