Title: [233046] tags/Safari-606.1.22/Source/_javascript_Core
Revision
233046
Author
kocsen_ch...@apple.com
Date
2018-06-21 11:35:40 -0700 (Thu, 21 Jun 2018)

Log Message

Cherry-pick r233039. rdar://problem/40910419

    Use IsoCellSets to track Executables with clearable code.
    https://bugs.webkit.org/show_bug.cgi?id=186877

    Reviewed by Filip Pizlo.

    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):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233039 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: tags/Safari-606.1.22/Source/_javascript_Core/ChangeLog (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/ChangeLog	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/ChangeLog	2018-06-21 18:35:40 UTC (rev 233046)
@@ -1,3 +1,168 @@
+2018-06-21  Kocsen Chung  <kocsen_ch...@apple.com>
+
+        Cherry-pick r233039. rdar://problem/40910419
+
+    Use IsoCellSets to track Executables with clearable code.
+    https://bugs.webkit.org/show_bug.cgi?id=186877
+    
+    Reviewed by Filip Pizlo.
+    
+    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):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233039 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2018-06-21  Mark Lam  <mark....@apple.com>
+
+            Use IsoCellSets to track Executables with clearable code.
+            https://bugs.webkit.org/show_bug.cgi?id=186877
+
+            Reviewed by Filip Pizlo.
+
+            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_mil...@apple.com>
 
         Expand concurrent GC assertion to accept JSValue() or 0

Modified: tags/Safari-606.1.22/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.cpp	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
         m_unlinkedCodeBlockForConstruct.set(vm, this, result);
         break;
     }
+    vm.unlinkedFunctionExecutableSpace.clearableCodeSet.add(this);
     return result;
 }
 

Modified: tags/Safari-606.1.22/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -58,6 +58,12 @@
     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 @@
 
     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)

Modified: tags/Safari-606.1.22/Source/_javascript_Core/heap/CodeBlockSetInlines.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/heap/CodeBlockSetInlines.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/heap/CodeBlockSetInlines.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
 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)));
                 });

Modified: tags/Safari-606.1.22/Source/_javascript_Core/heap/Heap.cpp (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/heap/Heap.cpp	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/heap/Heap.cpp	2018-06-21 18:35:40 UTC (rev 233046)
@@ -884,18 +884,27 @@
 {
     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 @@
         // 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 @@
 {
     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 @@
     WeakSet::deallocate(WeakImpl::asWeakImpl(slot));
 }
 
-void Heap::addExecutable(ExecutableBase* executable)
-{
-    m_executables.append(executable);
-}
-
 void Heap::collectNowFullIfNotDoneRecently(Synchronousness synchronousness)
 {
     if (!m_fullActivityCallback) {

Modified: tags/Safari-606.1.22/Source/_javascript_Core/heap/Heap.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/heap/Heap.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/heap/Heap.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -55,7 +55,6 @@
 class ConservativeRoots;
 class GCDeferralContext;
 class EdenGCActivityCallback;
-class ExecutableBase;
 class FullGCActivityCallback;
 class GCActivityCallback;
 class GCAwareJITStubRoutine;
@@ -165,7 +164,6 @@
     
     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 @@
     void finalizeMarkedUnconditionalFinalizers(CellSet&);
 
     void finalizeUnconditionalFinalizers();
-    
-    void clearUnmarkedExecutables();
+
     void deleteUnmarkedCompiledCode();
     JS_EXPORT_PRIVATE void addToRememberedSet(const JSCell*);
     void updateAllocationLimits();
@@ -628,8 +625,6 @@
     Seconds m_lastFullGCLength;
     Seconds m_lastEdenGCLength;
 
-    Vector<ExecutableBase*> m_executables;
-
     Vector<WeakBlock*> m_logicallyEmptyWeakBlocks;
     size_t m_indexOfNextLogicallyEmptyWeakBlockToSweep { WTF::notFound };
     

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/DirectEvalExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/DirectEvalExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/DirectEvalExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
     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*);

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/ExecutableBase.cpp (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/ExecutableBase.cpp	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/ExecutableBase.cpp	2018-06-21 18:35:40 UTC (rev 233046)
@@ -49,6 +49,43 @@
     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)

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/ExecutableBase.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/ExecutableBase.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/ExecutableBase.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -114,7 +114,8 @@
     }
 
     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;

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/FunctionExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/FunctionExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/FunctionExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -42,7 +42,7 @@
     template<typename CellType>
     static IsoSubspace* subspaceFor(VM& vm)
     {
-        return &vm.functionExecutableSpace;
+        return &vm.functionExecutableSpace.space;
     }
 
     static FunctionExecutable* create(

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/IndirectEvalExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/IndirectEvalExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/IndirectEvalExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
     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);

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/ModuleProgramExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/ModuleProgramExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/ModuleProgramExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
     template<typename CellType>
     static IsoSubspace* subspaceFor(VM& vm)
     {
-        return &vm.moduleProgramExecutableSpace;
+        return &vm.moduleProgramExecutableSpace.space;
     }
 
     static ModuleProgramExecutable* create(ExecState*, const SourceCode&);

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/ProgramExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/ProgramExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/ProgramExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
     template<typename CellType>
     static IsoSubspace* subspaceFor(VM& vm)
     {
-        return &vm.programExecutableSpace;
+        return &vm.programExecutableSpace.space;
     }
 
     static ProgramExecutable* create(ExecState* exec, const SourceCode& source)

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/ScriptExecutable.cpp (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/ScriptExecutable.cpp	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/ScriptExecutable.cpp	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
     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 @@
         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()));

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/ScriptExecutable.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/ScriptExecutable.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/ScriptExecutable.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -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 @@
     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 @@
     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())

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/VM.cpp (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/VM.cpp	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/VM.cpp	2018-06-21 18:35:40 UTC (rev 233046)
@@ -278,13 +278,10 @@
     , 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,7 +291,6 @@
     , 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)
@@ -301,7 +297,6 @@
 #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 @@
     , 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)

Modified: tags/Safari-606.1.22/Source/_javascript_Core/runtime/VM.h (233045 => 233046)


--- tags/Safari-606.1.22/Source/_javascript_Core/runtime/VM.h	2018-06-21 18:35:37 UTC (rev 233045)
+++ tags/Safari-606.1.22/Source/_javascript_Core/runtime/VM.h	2018-06-21 18:35:40 UTC (rev 233046)
@@ -352,13 +352,10 @@
     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,7 +365,6 @@
     IsoSubspace intlNumberFormatConstructorSpace;
     IsoSubspace intlPluralRulesConstructorSpace;
 #endif
-    IsoSubspace moduleProgramExecutableSpace;
     IsoSubspace nativeErrorConstructorSpace;
     IsoSubspace nativeExecutableSpace;
     IsoSubspace nativeStdFunctionSpace;
@@ -375,7 +371,6 @@
 #if JSC_OBJC_API_ENABLED
     IsoSubspace objCCallbackFunctionSpace;
 #endif
-    IsoSubspace programExecutableSpace;
     IsoSubspace propertyTableSpace;
     IsoSubspace proxyRevokeSpace;
     IsoSubspace regExpConstructorSpace;
@@ -431,7 +426,63 @@
         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;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to