void JSGlobalData::releaseExecutableMemory() { if (dynamicGlobalObject) { StackPreservingRecompiler recompiler; HashSet<JSCell*> roots; heap.getConservativeRegisterRoots(roots); HashSet<JSCell*>::iterator end = roots.end(); for (HashSet<JSCell*>::iterator ptr = roots.begin(); ptr != end; ++ptr) { ScriptExecutable* executable = 0; JSCell* cell = *ptr; if (cell->inherits(&ScriptExecutable::s_info)) executable = static_cast<ScriptExecutable*>(*ptr); else if (cell->inherits(&JSFunction::s_info)) { JSFunction* function = jsCast<JSFunction*>(*ptr); if (function->isHostFunction()) continue; executable = function->jsExecutable(); } else continue; ASSERT(executable->inherits(&ScriptExecutable::s_info)); executable->unlinkCalls(); if (executable->inherits(&FunctionExecutable::s_info)) recompiler.currentlyExecutingFunctions.add(static_cast<FunctionExecutable*>(executable)); } heap.objectSpace().forEachCell<StackPreservingRecompiler>(recompiler); } m_regExpCache->invalidateCode(); heap.collectAllGarbage(); }
void VM::releaseExecutableMemory() { prepareToDiscardCode(); if (entryScope) { StackPreservingRecompiler recompiler; HeapIterationScope iterationScope(heap); HashSet<JSCell*> roots; heap.getConservativeRegisterRoots(roots); HashSet<JSCell*>::iterator end = roots.end(); for (HashSet<JSCell*>::iterator ptr = roots.begin(); ptr != end; ++ptr) { ScriptExecutable* executable = 0; JSCell* cell = *ptr; if (cell->inherits(ScriptExecutable::info())) executable = static_cast<ScriptExecutable*>(*ptr); else if (cell->inherits(JSFunction::info())) { JSFunction* function = jsCast<JSFunction*>(*ptr); if (function->isHostFunction()) continue; executable = function->jsExecutable(); } else continue; ASSERT(executable->inherits(ScriptExecutable::info())); executable->unlinkCalls(); if (executable->inherits(FunctionExecutable::info())) recompiler.currentlyExecutingFunctions.add(static_cast<FunctionExecutable*>(executable)); } heap.objectSpace().forEachLiveCell<StackPreservingRecompiler>(iterationScope, recompiler); } m_regExpCache->invalidateCode(); heap.collectAllGarbage(); }
void InspectorHeapAgent::getPreview(ErrorString& errorString, int heapObjectId, Inspector::Protocol::OptOutput<String>* resultString, RefPtr<Inspector::Protocol::Debugger::FunctionDetails>& functionDetails, RefPtr<Inspector::Protocol::Runtime::ObjectPreview>& objectPreview) { // Prevent the cell from getting collected as we look it up. VM& vm = m_environment.vm(); JSLockHolder lock(vm); DeferGC deferGC(vm.heap); unsigned heapObjectIdentifier = static_cast<unsigned>(heapObjectId); const Optional<HeapSnapshotNode> optionalNode = nodeForHeapObjectIdentifier(errorString, heapObjectIdentifier); if (!optionalNode) return; // String preview. JSCell* cell = optionalNode->cell; if (cell->isString()) { *resultString = cell->getString(nullptr); return; } // FIXME: Provide preview information for Internal Objects? CodeBlock, Executable, etc. Structure* structure = cell->structure(m_environment.vm()); if (!structure) { errorString = ASCIILiteral("Unable to get object details - Structure"); return; } JSGlobalObject* globalObject = structure->globalObject(); if (!globalObject) { errorString = ASCIILiteral("Unable to get object details - GlobalObject"); return; } InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject->globalExec()); if (injectedScript.hasNoValue()) { errorString = ASCIILiteral("Unable to get object details - InjectedScript"); return; } // Function preview. if (cell->inherits(JSFunction::info())) { Deprecated::ScriptValue functionScriptValue(m_environment.vm(), JSValue(cell)); injectedScript.functionDetails(errorString, functionScriptValue, &functionDetails); return; } // Object preview. Deprecated::ScriptValue cellScriptValue(m_environment.vm(), JSValue(cell)); objectPreview = injectedScript.previewValue(cellScriptValue); }