WebKit Bugzilla
Attachment 343220 Details for
Bug 186877
: Use IsoCellSets to track Executables with clearable code.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
proposed patch.
bug-186877.patch (text/plain), 30.27 KB, created by
Mark Lam
on 2018-06-21 00:20:44 PDT
(
hide
)
Description:
proposed patch.
Filename:
MIME Type:
Creator:
Mark Lam
Created:
2018-06-21 00:20:44 PDT
Size:
30.27 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 233029) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,83 @@ >+2018-06-20 Mark Lam <mark.lam@apple.com> >+ >+ Use IsoCellSets to track Executables with clearable code. >+ https://bugs.webkit.org/show_bug.cgi?id=186877 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Hereâs an example of the results that this fix may yield: >+ 1. The workload: load cnn.com, wait for it to fully load, scroll down and up. >+ 2. Statistics on memory touched and memory freed by VM::deleteAllCode(): >+ >+ Visiting Executables: >+ Old New >+ Number of objects visited: 70897 14264 >+ Number of objects with deletable code: 14264 (20.1%) 14264 (100%) >+ Number of memory pages visited: 3224 1602 >+ Number of memory pages with deletable code: 1602 (49.7%) 1602 (100%) >+ >+ Visitng UnlinkedFunctionExecutables: >+ Old New >+ Number of objects visited: 105454 17231 >+ Number of objects with deletable code: 42319 (20.1%) 17231 (100%) ** >+ Number of memory pages visited: 4796 1349 >+ Number of memory pages with deletable code: 4013 (83.7%) 1349 (100%) >+ >+ ** The number of objects differ because the old code only visit unlinked >+ executables indirectly via linked executables, whereas the new behavior visit >+ all unlinked executables with deletable code directly. This means: >+ >+ a. we used to not visit unlinked executables that have not been linked yet >+ i.e. deleteAllCode() may not delete all code (especially code that is not >+ used). >+ b. we had to visit all linked executables to check if they of type >+ FunctionExecutable, before going on to visit their unlinked executable, and >+ this includes the ones that do not have deletable code. This means that we >+ would touch more memory in the process. >+ >+ Both of these these issues are now fixed with the new code. >+ >+ This code was tested with manually inserted instrumentation to track the above >+ statistics. It is not feasible to write an automated test for this without >+ leaving a lot of invasive instrumentation in the code. >+ >+ * bytecode/UnlinkedFunctionExecutable.cpp: >+ (JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor): >+ * bytecode/UnlinkedFunctionExecutable.h: >+ * heap/CodeBlockSetInlines.h: >+ (JSC::CodeBlockSet::iterateViaSubspaces): >+ * heap/Heap.cpp: >+ (JSC::Heap::deleteAllCodeBlocks): >+ (JSC::Heap::deleteAllUnlinkedCodeBlocks): >+ (JSC::Heap::deleteUnmarkedCompiledCode): >+ (JSC::Heap::clearUnmarkedExecutables): Deleted. >+ (JSC::Heap::addExecutable): Deleted. >+ * heap/Heap.h: >+ * runtime/DirectEvalExecutable.h: >+ >+ * runtime/ExecutableBase.cpp: >+ (JSC::ExecutableBase::hasClearableCode const): >+ - this is written based on the implementation of ExecutableBase::clearCode(). >+ >+ * runtime/ExecutableBase.h: >+ * runtime/FunctionExecutable.h: >+ * runtime/IndirectEvalExecutable.h: >+ * runtime/ModuleProgramExecutable.h: >+ * runtime/ProgramExecutable.h: >+ * runtime/ScriptExecutable.cpp: >+ (JSC::ScriptExecutable::clearCode): >+ (JSC::ScriptExecutable::installCode): >+ * runtime/ScriptExecutable.h: >+ (JSC::ScriptExecutable::finishCreation): >+ * runtime/VM.cpp: >+ (JSC::VM::VM): >+ * runtime/VM.h: >+ (JSC::VM::ScriptExecutableSpaceAndSet::ScriptExecutableSpaceAndSet): >+ (JSC::VM::ScriptExecutableSpaceAndSet::clearableCodeSetFor): >+ (JSC::VM::forEachScriptExecutableSpace): >+ (JSC::VM::UnlinkedFunctionExecutableSpaceAndSet::UnlinkedFunctionExecutableSpaceAndSet): >+ (JSC::VM::UnlinkedFunctionExecutableSpaceAndSet::clearableCodeSetFor): >+ > 2018-06-20 Keith Miller <keith_miller@apple.com> > > Expand concurrent GC assertion to accept JSValue() or 0 >Index: Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (revision 233029) >+++ Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp (working copy) >@@ -33,6 +33,7 @@ > #include "Debugger.h" > #include "ExecutableInfo.h" > #include "FunctionOverrides.h" >+#include "IsoCellSetInlines.h" > #include "JSCInlines.h" > #include "Parser.h" > #include "SourceProvider.h" >@@ -224,6 +225,7 @@ UnlinkedFunctionCodeBlock* UnlinkedFunct > m_unlinkedCodeBlockForConstruct.set(vm, this, result); > break; > } >+ vm.unlinkedFunctionExecutableSpace.clearableCodeSet.add(this); > return result; > } > >Index: Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h >=================================================================== >--- Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (revision 233029) >+++ Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h (working copy) >@@ -58,6 +58,12 @@ public: > typedef JSCell Base; > static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; > >+ template<typename CellType> >+ static IsoSubspace* subspaceFor(VM& vm) >+ { >+ return &vm.unlinkedFunctionExecutableSpace.space; >+ } >+ > static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, bool isBuiltinDefaultClassConstructor = false) > { > UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) >@@ -105,10 +111,11 @@ public: > > JS_EXPORT_PRIVATE FunctionExecutable* link(VM&, const SourceCode& parentSource, std::optional<int> overrideLineNumber = std::nullopt, Intrinsic = NoIntrinsic); > >- void clearCode() >+ void clearCode(VM& vm) > { > m_unlinkedCodeBlockForCall.clear(); > m_unlinkedCodeBlockForConstruct.clear(); >+ vm.unlinkedFunctionExecutableSpace.clearableCodeSet.remove(this); > } > > void recordParse(CodeFeatures features, bool hasCapturedVariables) >Index: Source/JavaScriptCore/heap/CodeBlockSetInlines.h >=================================================================== >--- Source/JavaScriptCore/heap/CodeBlockSetInlines.h (revision 233029) >+++ Source/JavaScriptCore/heap/CodeBlockSetInlines.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2016-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -59,8 +59,8 @@ template<typename Functor> > void CodeBlockSet::iterateViaSubspaces(VM& vm, const Functor& functor) > { > vm.forEachCodeBlockSpace( >- [&] (IsoSubspace& space) { >- space.forEachLiveCell( >+ [&] (auto& spaceAndSet) { >+ spaceAndSet.space.forEachLiveCell( > [&] (HeapCell* cell, HeapCell::Kind) { > functor(jsCast<CodeBlock*>(static_cast<JSCell*>(cell))); > }); >Index: Source/JavaScriptCore/heap/Heap.cpp >=================================================================== >--- Source/JavaScriptCore/heap/Heap.cpp (revision 233029) >+++ Source/JavaScriptCore/heap/Heap.cpp (working copy) >@@ -884,18 +884,27 @@ void Heap::deleteAllCodeBlocks(DeleteAll > { > if (m_collectionScope && effort == DeleteAllCodeIfNotCollecting) > return; >- >+ >+ VM& vm = *m_vm; > PreventCollectionScope preventCollectionScope(*this); > > // If JavaScript is running, it's not safe to delete all JavaScript code, since > // we'll end up returning to deleted code. >- RELEASE_ASSERT(!m_vm->entryScope); >+ RELEASE_ASSERT(!vm.entryScope); > RELEASE_ASSERT(!m_collectionScope); > > completeAllJITPlans(); > >- for (ExecutableBase* executable : m_executables) >- executable->clearCode(); >+ vm.forEachScriptExecutableSpace( >+ [&] (auto& spaceAndSet) { >+ HeapIterationScope heapIterationScope(*this); >+ auto& clearableCodeSet = spaceAndSet.clearableCodeSet; >+ clearableCodeSet.forEachLiveCell( >+ [&] (HeapCell* cell, HeapCell::Kind) { >+ ScriptExecutable* executable = static_cast<ScriptExecutable*>(cell); >+ executable->clearCode(clearableCodeSet); >+ }); >+ }); > > #if ENABLE(WEBASSEMBLY) > { >@@ -905,10 +914,10 @@ void Heap::deleteAllCodeBlocks(DeleteAll > // points into a CodeBlock that could be dead. The IC will still succeed because > // it uses a callee check, but then it will call into dead code. > HeapIterationScope heapIterationScope(*this); >- m_vm->webAssemblyCodeBlockSpace.forEachLiveCell([&] (HeapCell* cell, HeapCell::Kind kind) { >+ vm.webAssemblyCodeBlockSpace.forEachLiveCell([&] (HeapCell* cell, HeapCell::Kind kind) { > ASSERT_UNUSED(kind, kind == HeapCell::Kind::JSCell); > JSWebAssemblyCodeBlock* codeBlock = static_cast<JSWebAssemblyCodeBlock*>(cell); >- codeBlock->clearJSCallICs(*m_vm); >+ codeBlock->clearJSCallICs(vm); > }); > } > #endif >@@ -918,38 +927,23 @@ void Heap::deleteAllUnlinkedCodeBlocks(D > { > if (m_collectionScope && effort == DeleteAllCodeIfNotCollecting) > return; >- >+ >+ VM& vm = *m_vm; > PreventCollectionScope preventCollectionScope(*this); > > RELEASE_ASSERT(!m_collectionScope); >- >- for (ExecutableBase* current : m_executables) { >- if (!current->isFunctionExecutable()) >- continue; >- static_cast<FunctionExecutable*>(current)->unlinkedExecutable()->clearCode(); >- } >-} > >-void Heap::clearUnmarkedExecutables() >-{ >- for (unsigned i = m_executables.size(); i--;) { >- ExecutableBase* current = m_executables[i]; >- if (isMarked(current)) >- continue; >- >- // Eagerly dereference the Executable's JITCode in order to run watchpoint >- // destructors. Otherwise, watchpoints might fire for deleted CodeBlocks. >- current->clearCode(); >- std::swap(m_executables[i], m_executables.last()); >- m_executables.removeLast(); >- } >- >- m_executables.shrinkToFit(); >+ HeapIterationScope heapIterationScope(*this); >+ vm.unlinkedFunctionExecutableSpace.clearableCodeSet.forEachLiveCell( >+ [&] (HeapCell* cell, HeapCell::Kind) { >+ UnlinkedFunctionExecutable* executable = static_cast<UnlinkedFunctionExecutable*>(cell); >+ executable->clearCode(vm); >+ }); > } > > void Heap::deleteUnmarkedCompiledCode() > { >- clearUnmarkedExecutables(); >+ vm()->forEachScriptExecutableSpace([] (auto& space) { space.space.sweep(); }); > vm()->forEachCodeBlockSpace([] (auto& space) { space.space.sweep(); }); // Sweeping must occur before deleting stubs, otherwise the stubs might still think they're alive as they get deleted. > m_jitStubRoutines->deleteUnmarkedJettisonedStubRoutines(); > } >@@ -2380,11 +2374,6 @@ void Heap::FinalizerOwner::finalize(Hand > WeakSet::deallocate(WeakImpl::asWeakImpl(slot)); > } > >-void Heap::addExecutable(ExecutableBase* executable) >-{ >- m_executables.append(executable); >-} >- > void Heap::collectNowFullIfNotDoneRecently(Synchronousness synchronousness) > { > if (!m_fullActivityCallback) { >Index: Source/JavaScriptCore/heap/Heap.h >=================================================================== >--- Source/JavaScriptCore/heap/Heap.h (revision 233029) >+++ Source/JavaScriptCore/heap/Heap.h (working copy) >@@ -55,7 +55,6 @@ class CollectingScope; > class ConservativeRoots; > class GCDeferralContext; > class EdenGCActivityCallback; >-class ExecutableBase; > class FullGCActivityCallback; > class GCActivityCallback; > class GCAwareJITStubRoutine; >@@ -165,7 +164,6 @@ public: > > typedef void (*Finalizer)(JSCell*); > JS_EXPORT_PRIVATE void addFinalizer(JSCell*, Finalizer); >- void addExecutable(ExecutableBase*); > > void notifyIsSafeToCollect(); > bool isSafeToCollect() const { return m_isSafeToCollect; } >@@ -509,8 +507,7 @@ private: > void finalizeMarkedUnconditionalFinalizers(CellSet&); > > void finalizeUnconditionalFinalizers(); >- >- void clearUnmarkedExecutables(); >+ > void deleteUnmarkedCompiledCode(); > JS_EXPORT_PRIVATE void addToRememberedSet(const JSCell*); > void updateAllocationLimits(); >@@ -628,8 +625,6 @@ private: > Seconds m_lastFullGCLength; > Seconds m_lastEdenGCLength; > >- Vector<ExecutableBase*> m_executables; >- > Vector<WeakBlock*> m_logicallyEmptyWeakBlocks; > size_t m_indexOfNextLogicallyEmptyWeakBlockToSweep { WTF::notFound }; > >Index: Source/JavaScriptCore/runtime/DirectEvalExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/DirectEvalExecutable.h (revision 233029) >+++ Source/JavaScriptCore/runtime/DirectEvalExecutable.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2016-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,7 +34,7 @@ public: > template<typename CellType> > static IsoSubspace* subspaceFor(VM& vm) > { >- return &vm.directEvalExecutableSpace; >+ return &vm.directEvalExecutableSpace.space; > } > > static DirectEvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isArrowFunctionContext, EvalContextType, const VariableEnvironment*); >Index: Source/JavaScriptCore/runtime/ExecutableBase.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ExecutableBase.cpp (revision 233029) >+++ Source/JavaScriptCore/runtime/ExecutableBase.cpp (working copy) >@@ -49,6 +49,43 @@ void ExecutableBase::destroy(JSCell* cel > static_cast<ExecutableBase*>(cell)->ExecutableBase::~ExecutableBase(); > } > >+bool ExecutableBase::hasClearableCode() const >+{ >+ VM& vm = *this->vm(); >+ >+#if ENABLE(JIT) >+ if (m_jitCodeForCall >+ || m_jitCodeForConstruct >+ || m_jitCodeForCallWithArityCheck >+ || m_jitCodeForConstructWithArityCheck) >+ return true; >+#endif >+ >+ if (structure(vm)->classInfo() == FunctionExecutable::info()) { >+ auto* executable = static_cast<const FunctionExecutable*>(this); >+ if (executable->m_codeBlockForCall || executable->m_codeBlockForConstruct) >+ return true; >+ >+ } else if (structure(vm)->classInfo() == EvalExecutable::info()) { >+ auto* executable = static_cast<const EvalExecutable*>(this); >+ if (executable->m_evalCodeBlock || executable->m_unlinkedEvalCodeBlock) >+ return true; >+ >+ } else if (structure(vm)->classInfo() == ProgramExecutable::info()) { >+ auto* executable = static_cast<const ProgramExecutable*>(this); >+ if (executable->m_programCodeBlock || executable->m_unlinkedProgramCodeBlock) >+ return true; >+ >+ } else if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) { >+ auto* executable = static_cast<const ModuleProgramExecutable*>(this); >+ if (executable->m_moduleProgramCodeBlock >+ || executable->m_unlinkedModuleProgramCodeBlock >+ || executable->m_moduleEnvironmentSymbolTable) >+ return true; >+ } >+ return false; >+} >+ > void ExecutableBase::clearCode() > { > #if ENABLE(JIT) >Index: Source/JavaScriptCore/runtime/ExecutableBase.h >=================================================================== >--- Source/JavaScriptCore/runtime/ExecutableBase.h (revision 233029) >+++ Source/JavaScriptCore/runtime/ExecutableBase.h (working copy) >@@ -114,7 +114,8 @@ public: > } > > static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CellType, StructureFlags), info()); } >- >+ >+ bool hasClearableCode() const; > void clearCode(); > > DECLARE_EXPORT_INFO; >Index: Source/JavaScriptCore/runtime/FunctionExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/FunctionExecutable.h (revision 233029) >+++ Source/JavaScriptCore/runtime/FunctionExecutable.h (working copy) >@@ -42,7 +42,7 @@ public: > template<typename CellType> > static IsoSubspace* subspaceFor(VM& vm) > { >- return &vm.functionExecutableSpace; >+ return &vm.functionExecutableSpace.space; > } > > static FunctionExecutable* create( >Index: Source/JavaScriptCore/runtime/IndirectEvalExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/IndirectEvalExecutable.h (revision 233029) >+++ Source/JavaScriptCore/runtime/IndirectEvalExecutable.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2016-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,7 +34,7 @@ public: > template<typename CellType> > static IsoSubspace* subspaceFor(VM& vm) > { >- return &vm.indirectEvalExecutableSpace; >+ return &vm.indirectEvalExecutableSpace.space; > } > > static IndirectEvalExecutable* create(ExecState*, const SourceCode&, bool isInStrictContext, DerivedContextType, bool isArrowFunctionContext, EvalContextType); >Index: Source/JavaScriptCore/runtime/ModuleProgramExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/ModuleProgramExecutable.h (revision 233029) >+++ Source/JavaScriptCore/runtime/ModuleProgramExecutable.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2009-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -39,7 +39,7 @@ public: > template<typename CellType> > static IsoSubspace* subspaceFor(VM& vm) > { >- return &vm.moduleProgramExecutableSpace; >+ return &vm.moduleProgramExecutableSpace.space; > } > > static ModuleProgramExecutable* create(ExecState*, const SourceCode&); >Index: Source/JavaScriptCore/runtime/ProgramExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/ProgramExecutable.h (revision 233029) >+++ Source/JavaScriptCore/runtime/ProgramExecutable.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2009-2017 Apple Inc. All rights reserved. >+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -39,7 +39,7 @@ public: > template<typename CellType> > static IsoSubspace* subspaceFor(VM& vm) > { >- return &vm.programExecutableSpace; >+ return &vm.programExecutableSpace.space; > } > > static ProgramExecutable* create(ExecState* exec, const SourceCode& source) >Index: Source/JavaScriptCore/runtime/ScriptExecutable.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/ScriptExecutable.cpp (revision 233029) >+++ Source/JavaScriptCore/runtime/ScriptExecutable.cpp (working copy) >@@ -30,6 +30,7 @@ > #include "Debugger.h" > #include "EvalCodeBlock.h" > #include "FunctionCodeBlock.h" >+#include "IsoCellSetInlines.h" > #include "JIT.h" > #include "JSCInlines.h" > #include "LLIntEntrypoint.h" >@@ -70,6 +71,13 @@ void ScriptExecutable::destroy(JSCell* c > static_cast<ScriptExecutable*>(cell)->ScriptExecutable::~ScriptExecutable(); > } > >+void ScriptExecutable::clearCode(IsoCellSet& clearableCodeSet) >+{ >+ Base::clearCode(); >+ ASSERT(&VM::ScriptExecutableSpaceAndSet::clearableCodeSetFor(*subspace()) == &clearableCodeSet); >+ clearableCodeSet.remove(this); >+} >+ > void ScriptExecutable::installCode(CodeBlock* codeBlock) > { > installCode(*codeBlock->vm(), codeBlock, codeBlock->codeType(), codeBlock->specializationKind()); >@@ -147,6 +155,12 @@ void ScriptExecutable::installCode(VM& v > break; > } > >+ auto& clearableCodeSet = VM::ScriptExecutableSpaceAndSet::clearableCodeSetFor(*subspace()); >+ if (hasClearableCode()) >+ clearableCodeSet.add(this); >+ else >+ clearableCodeSet.remove(this); >+ > if (genericCodeBlock) { > RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this); > RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock->jitType())); >Index: Source/JavaScriptCore/runtime/ScriptExecutable.h >=================================================================== >--- Source/JavaScriptCore/runtime/ScriptExecutable.h (revision 233029) >+++ Source/JavaScriptCore/runtime/ScriptExecutable.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2009, 2010, 2013-2016 Apple Inc. All rights reserved. >+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -29,6 +29,8 @@ > > namespace JSC { > >+class IsoCellSet; >+ > class ScriptExecutable : public ExecutableBase { > public: > typedef ExecutableBase Base; >@@ -94,6 +96,8 @@ public: > CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception); > CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind); > >+ void clearCode(IsoCellSet&); >+ > // This function has an interesting GC story. Callers of this function are asking us to create a CodeBlock > // that is not jettisoned before this function returns. Callers are essentially asking for a strong reference > // to the CodeBlock. Because the Executable may be allocating the CodeBlock, we require callers to pass in >@@ -113,7 +117,6 @@ protected: > void finishCreation(VM& vm) > { > Base::finishCreation(vm); >- vm.heap.addExecutable(this); // Balanced by Heap::deleteUnmarkedCompiledCode(). > > #if ENABLE(CODEBLOCK_SAMPLING) > if (SamplingTool* sampler = vm.interpreter->sampler()) >Index: Source/JavaScriptCore/runtime/VM.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/VM.cpp (revision 233029) >+++ Source/JavaScriptCore/runtime/VM.cpp (working copy) >@@ -278,13 +278,10 @@ VM::VM(VMType vmType, HeapType heapType) > , boundFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSBoundFunction) > , callbackFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSCallbackFunction) > , customGetterSetterFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSCustomGetterSetterFunction) >- , directEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), DirectEvalExecutable) > , errorConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), ErrorConstructor) > , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellDangerousBitsHeapCellType.get(), ExecutableToCodeBlockEdge) >- , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable) > , functionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSFunction) > , generatorFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSGeneratorFunction) >- , indirectEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), IndirectEvalExecutable) > , inferredTypeSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredType) > , inferredValueSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredValue) > , internalFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), InternalFunction) >@@ -294,14 +291,12 @@ VM::VM(VMType vmType, HeapType heapType) > , intlNumberFormatConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), IntlNumberFormatConstructor) > , intlPluralRulesConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), IntlPluralRulesConstructor) > #endif >- , moduleProgramExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramExecutable) > , nativeErrorConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), NativeErrorConstructor) > , nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable) > , nativeStdFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSNativeStdFunction) > #if JSC_OBJC_API_ENABLED > , objCCallbackFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), ObjCCallbackFunction) > #endif >- , programExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramExecutable) > , propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable) > , proxyRevokeSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), ProxyRevoke) > , regExpConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), RegExpConstructor) >@@ -324,6 +319,12 @@ VM::VM(VMType vmType, HeapType heapType) > , functionCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionCodeBlock) > , moduleProgramCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramCodeBlock) > , programCodeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramCodeBlock) >+ , directEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), DirectEvalExecutable) >+ , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable) >+ , indirectEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), IndirectEvalExecutable) >+ , moduleProgramExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramExecutable) >+ , programExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramExecutable) >+ , unlinkedFunctionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), UnlinkedFunctionExecutable) > , vmType(vmType) > , clientData(0) > , topEntryFrame(nullptr) >Index: Source/JavaScriptCore/runtime/VM.h >=================================================================== >--- Source/JavaScriptCore/runtime/VM.h (revision 233029) >+++ Source/JavaScriptCore/runtime/VM.h (working copy) >@@ -352,13 +352,10 @@ public: > IsoSubspace boundFunctionSpace; > IsoSubspace callbackFunctionSpace; > IsoSubspace customGetterSetterFunctionSpace; >- IsoSubspace directEvalExecutableSpace; > IsoSubspace errorConstructorSpace; > IsoSubspace executableToCodeBlockEdgeSpace; >- IsoSubspace functionExecutableSpace; > IsoSubspace functionSpace; > IsoSubspace generatorFunctionSpace; >- IsoSubspace indirectEvalExecutableSpace; > IsoSubspace inferredTypeSpace; > IsoSubspace inferredValueSpace; > IsoSubspace internalFunctionSpace; >@@ -368,14 +365,12 @@ public: > IsoSubspace intlNumberFormatConstructorSpace; > IsoSubspace intlPluralRulesConstructorSpace; > #endif >- IsoSubspace moduleProgramExecutableSpace; > IsoSubspace nativeErrorConstructorSpace; > IsoSubspace nativeExecutableSpace; > IsoSubspace nativeStdFunctionSpace; > #if JSC_OBJC_API_ENABLED > IsoSubspace objCCallbackFunctionSpace; > #endif >- IsoSubspace programExecutableSpace; > IsoSubspace propertyTableSpace; > IsoSubspace proxyRevokeSpace; > IsoSubspace regExpConstructorSpace; >@@ -431,7 +426,63 @@ public: > func(moduleProgramCodeBlockSpace); > func(programCodeBlockSpace); > } >- >+ >+ struct ScriptExecutableSpaceAndSet { >+ IsoSubspace space; >+ IsoCellSet clearableCodeSet; >+ >+ template<typename... Arguments> >+ ScriptExecutableSpaceAndSet(Arguments&&... arguments) >+ : space(std::forward<Arguments>(arguments)...) >+ , clearableCodeSet(space) >+ { } >+ >+ static IsoCellSet& clearableCodeSetFor(Subspace& space) >+ { >+ return *bitwise_cast<IsoCellSet*>( >+ bitwise_cast<char*>(&space) - >+ OBJECT_OFFSETOF(ScriptExecutableSpaceAndSet, space) + >+ OBJECT_OFFSETOF(ScriptExecutableSpaceAndSet, clearableCodeSet)); >+ } >+ }; >+ >+ ScriptExecutableSpaceAndSet directEvalExecutableSpace; >+ ScriptExecutableSpaceAndSet functionExecutableSpace; >+ ScriptExecutableSpaceAndSet indirectEvalExecutableSpace; >+ ScriptExecutableSpaceAndSet moduleProgramExecutableSpace; >+ ScriptExecutableSpaceAndSet programExecutableSpace; >+ >+ template<typename Func> >+ void forEachScriptExecutableSpace(const Func& func) >+ { >+ func(directEvalExecutableSpace); >+ func(functionExecutableSpace); >+ func(indirectEvalExecutableSpace); >+ func(moduleProgramExecutableSpace); >+ func(programExecutableSpace); >+ } >+ >+ struct UnlinkedFunctionExecutableSpaceAndSet { >+ IsoSubspace space; >+ IsoCellSet clearableCodeSet; >+ >+ template<typename... Arguments> >+ UnlinkedFunctionExecutableSpaceAndSet(Arguments&&... arguments) >+ : space(std::forward<Arguments>(arguments)...) >+ , clearableCodeSet(space) >+ { } >+ >+ static IsoCellSet& clearableCodeSetFor(Subspace& space) >+ { >+ return *bitwise_cast<IsoCellSet*>( >+ bitwise_cast<char*>(&space) - >+ OBJECT_OFFSETOF(UnlinkedFunctionExecutableSpaceAndSet, space) + >+ OBJECT_OFFSETOF(UnlinkedFunctionExecutableSpaceAndSet, clearableCodeSet)); >+ } >+ }; >+ >+ UnlinkedFunctionExecutableSpaceAndSet unlinkedFunctionExecutableSpace; >+ > VMType vmType; > ClientData* clientData; > EntryFrame* topEntryFrame;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186877
: 343220 |
343236