Title: [262450] branches/safari-610.1.15-branch/Source
Revision
262450
Author
alanc...@apple.com
Date
2020-06-02 14:58:25 -0700 (Tue, 02 Jun 2020)

Log Message

Cherry-pick r262434. rdar://problem/63891520

    Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
    https://bugs.webkit.org/show_bug.cgi?id=212585
    <rdar://problem/63812487>

    Reviewed by Yusuke Suzuki.

    Source/bmalloc:

    1. Gigacage::Config now reserves and expect space to be available in an external
       WebConfig::g_config buffer.  Gigacage does not allocate that buffer.

    2. Moved Gigacage::Config to GigacageConfig.h.
       This allows WTFConfig.h to include GigacageConfig.h instead of all of Gigacage.h.

    3. Moved Gigacage::Kind to GigacageKind.h.
       Otherwise, Gigacage::Kind would need to move to GigacageConfig.h which is a
       weird place to put it.

    4. Removed freezeGigacageConfig(), unfreezeGigacageConfig(), and
       permanentlyFreezeGigacageConfig().

       It is no longer possible to temporarily freeze and unfreeze the Gigacage::Config
       because it now share the same memory page with higher level Configs.

       permanentlyFreezeGigacageConfig() is no longer needed because it is subsumed
       by WTF::Config::permanentlyFreeze(), which will freeze the entire WebConfig::g_config
       buffer.

       One difference in behavior here is that Gigacage::Config data used to be permanently
       frozen as soon as forbidDisablingPrimitiveGigacage() is called.  Now, it isn't
       permanently frozen until the end of the construction of the first JSC::VM instance
       in the process (just like the other Config records).  This still guarantees that
       it is frozen before any JS script can run.

    5. Previously, disablePrimitiveGigacage() works by nullifying the Primitive gigacage
       base pointer.  We can no longer do that because the base pointer will be frozen
       on VM instantiation.  Instead, if not forbidden, we now disable the Primitive
       gigacage by setting a disablePrimitiveGigacageRequested bool variable that is
       not frozen in the Gigacage::Config.

       To check if the Primitive gigacage is enabled, the LLInt, AssemblyHelpers::cageConditionally(),
       and runtime functions will check the following conditions:

           g_gigacageConfig.basePtr(Primitive) &&
               (disablingPrimitiveGigacageIsForbidden() || disableNotRequestedForPrimitiveGigacage())

           The base pointer being null means the gigacage was never set up.

           If disablingPrimitiveGigacageIsForbidden() is true, then we don't care
           whether a disable request has been received.

           Otherwise, the gigacage is only enabled if it has been set up, and a
           disable request has not been received.

           Note that the first 2 terms are frozen in the Gigacage::Config.  Only the
           last term is a runtime variable.  If disabling is forbidden, then the
           runtime variable never comes into play.

       The FTL does not rely on a runtime check for whether the Primitive gigacage is
       enabled or not.  Instead, it relies on a watchpoint to handle this.  So, it
       just works, and there's no performance penalty with adding the 2 extra terms
       to check.

       Note also that the jsc shell and the WebProcess will forbid disabling of the
       Primitive gigacage.  This means the AssemblyHelpers::cageConditionally() will
       also not generate the runtime checks for the 2 extra terms.

       Only the LLInt and runtime functions will have to do work to check the 2 extra
       terms.  But because these are not in perf critical paths, this is ok.

       Note that we're deliberately gating the disablePrimitiveGigacageRequested
       variable check on disablingPrimitiveGigacageIsForbidden though, logically, the
       isEnable check does not really depend on whether disabling is forbidden or not.
       We do this because disablingPrimitiveGigacageIsForbidden is frozen in the Config,
       and it is, therefore, a stronger guarantee of correctness whereas the variable
       can be corrupted.

    6. Replaced isDisablingPrimitiveGigacageForbidden(), canPrimitiveGigacageBeDisabled(),
       and isPrimitiveGigacagePermanentlyEnabled() with disablingPrimitiveGigacageIsForbidden().

    * CMakeLists.txt:
    * bmalloc.xcodeproj/project.pbxproj:
    * bmalloc/Gigacage.cpp:
    (Gigacage::ensureGigacage):
    (Gigacage::disablePrimitiveGigacage):
    (Gigacage::forbidDisablingPrimitiveGigacage):
    (Gigacage::bmalloc::freezeGigacageConfig): Deleted.
    (Gigacage::bmalloc::unfreezeGigacageConfig): Deleted.
    (Gigacage::bmalloc::permanentlyFreezeGigacageConfig): Deleted.
    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope): Deleted.
    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope): Deleted.
    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
    * bmalloc/Gigacage.h:
    (Gigacage::disablingPrimitiveGigacageIsForbidden):
    (Gigacage::disableNotRequestedForPrimitiveGigacage):
    (Gigacage::isEnabled):
    (Gigacage::basePtr):
    (Gigacage::caged):
    (Gigacage::forbidDisablingPrimitiveGigacage):
    (): Deleted.
    (Gigacage::Config::basePtr const): Deleted.
    (Gigacage::Config::setBasePtr): Deleted.
    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
    * bmalloc/GigacageConfig.h: Added.
    (Gigacage::Config::basePtr const):
    (Gigacage::Config::setBasePtr):
    * bmalloc/GigacageKind.h: Added.
    * bmalloc/Heap.cpp:
    (bmalloc::Heap::usingGigacage):
    * bmalloc/mbmalloc.cpp:

    Source/_javascript_Core:

    * assembler/testmasm.cpp:
    (JSC::testCagePreservesPACFailureBit):
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
    * ftl/FTLLowerDFGToB3.cpp:
    (JSC::FTL::DFG::LowerDFGToB3::caged):
    * jit/AssemblyHelpers.h:
    (JSC::AssemblyHelpers::cageConditionally):
    * llint/LowLevelInterpreter64.asm:
    * runtime/JSCConfig.h:
    (JSC::Config::isPermanentlyFrozen):

    Source/WTF:

    We now think of the various Config records as being allocated from parts of a
    WebConfig::g_config buffer.  WTF::Config will manage the mechanics of freezing
    that buffer.  And the JSC VM is still the determiner of if/when to freeze the
    buffer, and it will do this at the end of the construction of the very first
    VM instance (as before).

    Gigacage::Config reserves space in WebConfig::g_config.
    WTF::Config will honor that reservation and place itself after that.
    JSC::Config will continue to place itself at WTF::Config::spaceForExtensions.

    The upside of this approach this is that we can now share the same memory page
    for all the Configs, and can freeze them in one go.

    The downside is that g_gigacageConfig, g_wtfConfig, and g_jscConfig now have to
    be macros.  This results in some weirdness e.g. they are no longer qualified by
    namespaces: referring to WTF::g_wtfConfig is now incorrect.

    * wtf/Gigacage.h:
    (Gigacage::disablingPrimitiveGigacageIsForbidden):
    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
    * wtf/WTFConfig.cpp:
    (WTF::Config::permanentlyFreeze):
    * wtf/WTFConfig.h:
    (): Deleted.

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/ChangeLog (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/ChangeLog	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/ChangeLog	2020-06-02 21:58:25 UTC (rev 262450)
@@ -1,5 +1,188 @@
 2020-06-02  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r262434. rdar://problem/63891520
+
+    Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
+    https://bugs.webkit.org/show_bug.cgi?id=212585
+    <rdar://problem/63812487>
+    
+    Reviewed by Yusuke Suzuki.
+    
+    Source/bmalloc:
+    
+    1. Gigacage::Config now reserves and expect space to be available in an external
+       WebConfig::g_config buffer.  Gigacage does not allocate that buffer.
+    
+    2. Moved Gigacage::Config to GigacageConfig.h.
+       This allows WTFConfig.h to include GigacageConfig.h instead of all of Gigacage.h.
+    
+    3. Moved Gigacage::Kind to GigacageKind.h.
+       Otherwise, Gigacage::Kind would need to move to GigacageConfig.h which is a
+       weird place to put it.
+    
+    4. Removed freezeGigacageConfig(), unfreezeGigacageConfig(), and
+       permanentlyFreezeGigacageConfig().
+    
+       It is no longer possible to temporarily freeze and unfreeze the Gigacage::Config
+       because it now share the same memory page with higher level Configs.
+    
+       permanentlyFreezeGigacageConfig() is no longer needed because it is subsumed
+       by WTF::Config::permanentlyFreeze(), which will freeze the entire WebConfig::g_config
+       buffer.
+    
+       One difference in behavior here is that Gigacage::Config data used to be permanently
+       frozen as soon as forbidDisablingPrimitiveGigacage() is called.  Now, it isn't
+       permanently frozen until the end of the construction of the first JSC::VM instance
+       in the process (just like the other Config records).  This still guarantees that
+       it is frozen before any JS script can run.
+    
+    5. Previously, disablePrimitiveGigacage() works by nullifying the Primitive gigacage
+       base pointer.  We can no longer do that because the base pointer will be frozen
+       on VM instantiation.  Instead, if not forbidden, we now disable the Primitive
+       gigacage by setting a disablePrimitiveGigacageRequested bool variable that is
+       not frozen in the Gigacage::Config.
+    
+       To check if the Primitive gigacage is enabled, the LLInt, AssemblyHelpers::cageConditionally(),
+       and runtime functions will check the following conditions:
+    
+           g_gigacageConfig.basePtr(Primitive) &&
+               (disablingPrimitiveGigacageIsForbidden() || disableNotRequestedForPrimitiveGigacage())
+    
+           The base pointer being null means the gigacage was never set up.
+    
+           If disablingPrimitiveGigacageIsForbidden() is true, then we don't care
+           whether a disable request has been received.
+    
+           Otherwise, the gigacage is only enabled if it has been set up, and a
+           disable request has not been received.
+    
+           Note that the first 2 terms are frozen in the Gigacage::Config.  Only the
+           last term is a runtime variable.  If disabling is forbidden, then the
+           runtime variable never comes into play.
+    
+       The FTL does not rely on a runtime check for whether the Primitive gigacage is
+       enabled or not.  Instead, it relies on a watchpoint to handle this.  So, it
+       just works, and there's no performance penalty with adding the 2 extra terms
+       to check.
+    
+       Note also that the jsc shell and the WebProcess will forbid disabling of the
+       Primitive gigacage.  This means the AssemblyHelpers::cageConditionally() will
+       also not generate the runtime checks for the 2 extra terms.
+    
+       Only the LLInt and runtime functions will have to do work to check the 2 extra
+       terms.  But because these are not in perf critical paths, this is ok.
+    
+       Note that we're deliberately gating the disablePrimitiveGigacageRequested
+       variable check on disablingPrimitiveGigacageIsForbidden though, logically, the
+       isEnable check does not really depend on whether disabling is forbidden or not.
+       We do this because disablingPrimitiveGigacageIsForbidden is frozen in the Config,
+       and it is, therefore, a stronger guarantee of correctness whereas the variable
+       can be corrupted.
+    
+    6. Replaced isDisablingPrimitiveGigacageForbidden(), canPrimitiveGigacageBeDisabled(),
+       and isPrimitiveGigacagePermanentlyEnabled() with disablingPrimitiveGigacageIsForbidden().
+    
+    * CMakeLists.txt:
+    * bmalloc.xcodeproj/project.pbxproj:
+    * bmalloc/Gigacage.cpp:
+    (Gigacage::ensureGigacage):
+    (Gigacage::disablePrimitiveGigacage):
+    (Gigacage::forbidDisablingPrimitiveGigacage):
+    (Gigacage::bmalloc::freezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::unfreezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::permanentlyFreezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope): Deleted.
+    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope): Deleted.
+    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+    * bmalloc/Gigacage.h:
+    (Gigacage::disablingPrimitiveGigacageIsForbidden):
+    (Gigacage::disableNotRequestedForPrimitiveGigacage):
+    (Gigacage::isEnabled):
+    (Gigacage::basePtr):
+    (Gigacage::caged):
+    (Gigacage::forbidDisablingPrimitiveGigacage):
+    (): Deleted.
+    (Gigacage::Config::basePtr const): Deleted.
+    (Gigacage::Config::setBasePtr): Deleted.
+    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+    * bmalloc/GigacageConfig.h: Added.
+    (Gigacage::Config::basePtr const):
+    (Gigacage::Config::setBasePtr):
+    * bmalloc/GigacageKind.h: Added.
+    * bmalloc/Heap.cpp:
+    (bmalloc::Heap::usingGigacage):
+    * bmalloc/mbmalloc.cpp:
+    
+    Source/_javascript_Core:
+    
+    * assembler/testmasm.cpp:
+    (JSC::testCagePreservesPACFailureBit):
+    * dfg/DFGSpeculativeJIT.cpp:
+    (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
+    * ftl/FTLLowerDFGToB3.cpp:
+    (JSC::FTL::DFG::LowerDFGToB3::caged):
+    * jit/AssemblyHelpers.h:
+    (JSC::AssemblyHelpers::cageConditionally):
+    * llint/LowLevelInterpreter64.asm:
+    * runtime/JSCConfig.h:
+    (JSC::Config::isPermanentlyFrozen):
+    
+    Source/WTF:
+    
+    We now think of the various Config records as being allocated from parts of a
+    WebConfig::g_config buffer.  WTF::Config will manage the mechanics of freezing
+    that buffer.  And the JSC VM is still the determiner of if/when to freeze the
+    buffer, and it will do this at the end of the construction of the very first
+    VM instance (as before).
+    
+    Gigacage::Config reserves space in WebConfig::g_config.
+    WTF::Config will honor that reservation and place itself after that.
+    JSC::Config will continue to place itself at WTF::Config::spaceForExtensions.
+    
+    The upside of this approach this is that we can now share the same memory page
+    for all the Configs, and can freeze them in one go.
+    
+    The downside is that g_gigacageConfig, g_wtfConfig, and g_jscConfig now have to
+    be macros.  This results in some weirdness e.g. they are no longer qualified by
+    namespaces: referring to WTF::g_wtfConfig is now incorrect.
+    
+    * wtf/Gigacage.h:
+    (Gigacage::disablingPrimitiveGigacageIsForbidden):
+    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+    * wtf/WTFConfig.cpp:
+    (WTF::Config::permanentlyFreeze):
+    * wtf/WTFConfig.h:
+    (): Deleted.
+    
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262434 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-06-02  Mark Lam  <mark....@apple.com>
+
+            Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
+            https://bugs.webkit.org/show_bug.cgi?id=212585
+            <rdar://problem/63812487>
+
+            Reviewed by Yusuke Suzuki.
+
+            * assembler/testmasm.cpp:
+            (JSC::testCagePreservesPACFailureBit):
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
+            * ftl/FTLLowerDFGToB3.cpp:
+            (JSC::FTL::DFG::LowerDFGToB3::caged):
+            * jit/AssemblyHelpers.h:
+            (JSC::AssemblyHelpers::cageConditionally):
+            * llint/LowLevelInterpreter64.asm:
+            * runtime/JSCConfig.h:
+            (JSC::Config::isPermanentlyFrozen):
+
+2020-06-02  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r262356. rdar://problem/63891520
 
     Change JSC::Config to use storage in WTF::Config instead of its own.

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/assembler/testmasm.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/assembler/testmasm.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/assembler/testmasm.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -2115,7 +2115,7 @@
     if (!Gigacage::shouldBeEnabled())
         return;
 
-    RELEASE_ASSERT(!Gigacage::isDisablingPrimitiveGigacageForbidden());
+    RELEASE_ASSERT(!Gigacage::disablingPrimitiveGigacageIsForbidden());
     auto cage = compile([] (CCallHelpers& jit) {
         emitFunctionPrologue(jit);
         jit.cageConditionally(Gigacage::Primitive, GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2);

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -7247,7 +7247,7 @@
         return;
     }
     
-    if (Gigacage::canPrimitiveGigacageBeDisabled()) {
+    if (!Gigacage::disablingPrimitiveGigacageIsForbidden()) {
         VM& vm = this->vm();
         if (vm.primitiveGigacageEnabled().isStillValid())
             m_jit.graph().watchpoints().addLazily(vm.primitiveGigacageEnabled());

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -15807,7 +15807,7 @@
         if (!Gigacage::isEnabled(kind))
             return doUntagArrayPtr(ptr);
         
-        if (kind == Gigacage::Primitive && Gigacage::canPrimitiveGigacageBeDisabled()) {
+        if (kind == Gigacage::Primitive && !Gigacage::disablingPrimitiveGigacageIsForbidden()) {
             if (vm().primitiveGigacageEnabled().isStillValid())
                 m_graph.watchpoints().addLazily(vm().primitiveGigacageEnabled());
             else

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/jit/AssemblyHelpers.h (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/jit/AssemblyHelpers.h	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/jit/AssemblyHelpers.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -1691,7 +1691,7 @@
     {
 #if GIGACAGE_ENABLED
         if (Gigacage::isEnabled(kind)) {
-            if (kind != Gigacage::Primitive || Gigacage::isDisablingPrimitiveGigacageForbidden())
+            if (kind != Gigacage::Primitive || Gigacage::disablingPrimitiveGigacageIsForbidden())
                 cageWithoutUntagging(kind, storage);
             else {
 #if CPU(ARM64E)
@@ -1698,8 +1698,11 @@
                 if (length == scratch)
                     scratch = getCachedMemoryTempRegisterIDAndInvalidate();
 #endif
+                JumpList done;
+                done.append(branchTest8(NonZero, AbsoluteAddress(&Gigacage::disablePrimitiveGigacageRequested)));
+
                 loadPtr(Gigacage::addressOfBasePtr(kind), scratch);
-                Jump done = branchTest64(Zero, scratch);
+                done.append(branchTest64(Zero, scratch));
 #if CPU(ARM64E)
                 GPRReg tempReg = getCachedDataTempRegisterIDAndInvalidate();
                 move(storage, tempReg);

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2020-06-02 21:58:25 UTC (rev 262450)
@@ -424,6 +424,20 @@
     end
 end
 
+macro cagePrimitive(basePtr, mask, ptr, scratch)
+    if GIGACAGE_ENABLED and not (C_LOOP or C_LOOP_WIN)
+        loadb _g_config + (constexpr Gigacage::startOffsetOfGigacageConfig) + Gigacage::Config::disablingPrimitiveGigacageIsForbidden, scratch
+        btbnz scratch, .doCaging
+
+        loadb _disablePrimitiveGigacageRequested, scratch
+        btbnz scratch, .done
+
+    .doCaging:
+        cage(basePtr, mask, ptr, scratch)
+    .done:
+    end
+end
+
 macro cagedPrimitive(ptr, length, scratch, scratch2)
     if ARM64E
         const source = scratch2
@@ -432,7 +446,7 @@
         const source = ptr
     end
     if GIGACAGE_ENABLED
-        cage(_g_gigacageConfig + Gigacage::Config::basePtrs + GigacagePrimitiveBasePtrOffset, constexpr Gigacage::primitiveGigacageMask, source, scratch)
+        cagePrimitive(_g_config + (constexpr Gigacage::startOffsetOfGigacageConfig) + Gigacage::Config::basePtrs + GigacagePrimitiveBasePtrOffset, constexpr Gigacage::primitiveGigacageMask, source, scratch)
         if ARM64E
             const numberOfPACBits = constexpr MacroAssembler::numberOfPACBits
             bfiq scratch2, 0, 64 - numberOfPACBits, ptr
@@ -446,7 +460,7 @@
 macro loadCagedJSValue(source, dest, scratchOrLength)
     loadp source, dest
     if GIGACAGE_ENABLED
-        cage(_g_gigacageConfig + Gigacage::Config::basePtrs + GigacageJSValueBasePtrOffset, constexpr Gigacage::jsValueGigacageMask, dest, scratchOrLength)
+        cage(_g_config + (constexpr Gigacage::startOffsetOfGigacageConfig) + Gigacage::Config::basePtrs + GigacageJSValueBasePtrOffset, constexpr Gigacage::jsValueGigacageMask, dest, scratchOrLength)
     end
 end
 

Modified: branches/safari-610.1.15-branch/Source/_javascript_Core/runtime/JSCConfig.h (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/_javascript_Core/runtime/JSCConfig.h	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/_javascript_Core/runtime/JSCConfig.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -51,7 +51,7 @@
         enableRestrictedOptions();
     }
 
-    bool isPermanentlyFrozen() { return WTF::g_wtfConfig.isPermanentlyFrozen; }
+    bool isPermanentlyFrozen() { return g_wtfConfig.isPermanentlyFrozen; }
 
     // All the fields in this struct should be chosen such that their
     // initial value is 0 / null / falsy because Config is instantiated
@@ -82,12 +82,11 @@
     WTF::PtrTagLookup ptrTagLookupRecord;
 };
 
-constexpr size_t offsetOfWTFConfigExtension = offsetof(WTF::Config, spaceForExtensions);
 constexpr size_t alignmentOfJSCConfig = std::alignment_of<JSC::Config>::value;
 
-static_assert(sizeof(JSC::Config) <= (sizeof(WTF::Config) - offsetOfWTFConfigExtension));
-static_assert(roundUpToMultipleOf<alignmentOfJSCConfig>(offsetOfWTFConfigExtension) == offsetOfWTFConfigExtension);
+static_assert(WTF::offsetOfWTFConfigExtension + sizeof(JSC::Config) <= WTF::ConfigSizeToProtect);
+static_assert(roundUpToMultipleOf<alignmentOfJSCConfig>(WTF::offsetOfWTFConfigExtension) == WTF::offsetOfWTFConfigExtension);
 
-#define g_jscConfig (*bitwise_cast<Config*>(&WTF::g_wtfConfig.spaceForExtensions))
+#define g_jscConfig (*bitwise_cast<JSC::Config*>(&g_wtfConfig.spaceForExtensions))
 
 } // namespace JSC

Modified: branches/safari-610.1.15-branch/Source/WTF/ChangeLog (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/WTF/ChangeLog	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/WTF/ChangeLog	2020-06-02 21:58:25 UTC (rev 262450)
@@ -1,5 +1,203 @@
 2020-06-02  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r262434. rdar://problem/63891520
+
+    Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
+    https://bugs.webkit.org/show_bug.cgi?id=212585
+    <rdar://problem/63812487>
+    
+    Reviewed by Yusuke Suzuki.
+    
+    Source/bmalloc:
+    
+    1. Gigacage::Config now reserves and expect space to be available in an external
+       WebConfig::g_config buffer.  Gigacage does not allocate that buffer.
+    
+    2. Moved Gigacage::Config to GigacageConfig.h.
+       This allows WTFConfig.h to include GigacageConfig.h instead of all of Gigacage.h.
+    
+    3. Moved Gigacage::Kind to GigacageKind.h.
+       Otherwise, Gigacage::Kind would need to move to GigacageConfig.h which is a
+       weird place to put it.
+    
+    4. Removed freezeGigacageConfig(), unfreezeGigacageConfig(), and
+       permanentlyFreezeGigacageConfig().
+    
+       It is no longer possible to temporarily freeze and unfreeze the Gigacage::Config
+       because it now share the same memory page with higher level Configs.
+    
+       permanentlyFreezeGigacageConfig() is no longer needed because it is subsumed
+       by WTF::Config::permanentlyFreeze(), which will freeze the entire WebConfig::g_config
+       buffer.
+    
+       One difference in behavior here is that Gigacage::Config data used to be permanently
+       frozen as soon as forbidDisablingPrimitiveGigacage() is called.  Now, it isn't
+       permanently frozen until the end of the construction of the first JSC::VM instance
+       in the process (just like the other Config records).  This still guarantees that
+       it is frozen before any JS script can run.
+    
+    5. Previously, disablePrimitiveGigacage() works by nullifying the Primitive gigacage
+       base pointer.  We can no longer do that because the base pointer will be frozen
+       on VM instantiation.  Instead, if not forbidden, we now disable the Primitive
+       gigacage by setting a disablePrimitiveGigacageRequested bool variable that is
+       not frozen in the Gigacage::Config.
+    
+       To check if the Primitive gigacage is enabled, the LLInt, AssemblyHelpers::cageConditionally(),
+       and runtime functions will check the following conditions:
+    
+           g_gigacageConfig.basePtr(Primitive) &&
+               (disablingPrimitiveGigacageIsForbidden() || disableNotRequestedForPrimitiveGigacage())
+    
+           The base pointer being null means the gigacage was never set up.
+    
+           If disablingPrimitiveGigacageIsForbidden() is true, then we don't care
+           whether a disable request has been received.
+    
+           Otherwise, the gigacage is only enabled if it has been set up, and a
+           disable request has not been received.
+    
+           Note that the first 2 terms are frozen in the Gigacage::Config.  Only the
+           last term is a runtime variable.  If disabling is forbidden, then the
+           runtime variable never comes into play.
+    
+       The FTL does not rely on a runtime check for whether the Primitive gigacage is
+       enabled or not.  Instead, it relies on a watchpoint to handle this.  So, it
+       just works, and there's no performance penalty with adding the 2 extra terms
+       to check.
+    
+       Note also that the jsc shell and the WebProcess will forbid disabling of the
+       Primitive gigacage.  This means the AssemblyHelpers::cageConditionally() will
+       also not generate the runtime checks for the 2 extra terms.
+    
+       Only the LLInt and runtime functions will have to do work to check the 2 extra
+       terms.  But because these are not in perf critical paths, this is ok.
+    
+       Note that we're deliberately gating the disablePrimitiveGigacageRequested
+       variable check on disablingPrimitiveGigacageIsForbidden though, logically, the
+       isEnable check does not really depend on whether disabling is forbidden or not.
+       We do this because disablingPrimitiveGigacageIsForbidden is frozen in the Config,
+       and it is, therefore, a stronger guarantee of correctness whereas the variable
+       can be corrupted.
+    
+    6. Replaced isDisablingPrimitiveGigacageForbidden(), canPrimitiveGigacageBeDisabled(),
+       and isPrimitiveGigacagePermanentlyEnabled() with disablingPrimitiveGigacageIsForbidden().
+    
+    * CMakeLists.txt:
+    * bmalloc.xcodeproj/project.pbxproj:
+    * bmalloc/Gigacage.cpp:
+    (Gigacage::ensureGigacage):
+    (Gigacage::disablePrimitiveGigacage):
+    (Gigacage::forbidDisablingPrimitiveGigacage):
+    (Gigacage::bmalloc::freezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::unfreezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::permanentlyFreezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope): Deleted.
+    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope): Deleted.
+    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+    * bmalloc/Gigacage.h:
+    (Gigacage::disablingPrimitiveGigacageIsForbidden):
+    (Gigacage::disableNotRequestedForPrimitiveGigacage):
+    (Gigacage::isEnabled):
+    (Gigacage::basePtr):
+    (Gigacage::caged):
+    (Gigacage::forbidDisablingPrimitiveGigacage):
+    (): Deleted.
+    (Gigacage::Config::basePtr const): Deleted.
+    (Gigacage::Config::setBasePtr): Deleted.
+    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+    * bmalloc/GigacageConfig.h: Added.
+    (Gigacage::Config::basePtr const):
+    (Gigacage::Config::setBasePtr):
+    * bmalloc/GigacageKind.h: Added.
+    * bmalloc/Heap.cpp:
+    (bmalloc::Heap::usingGigacage):
+    * bmalloc/mbmalloc.cpp:
+    
+    Source/_javascript_Core:
+    
+    * assembler/testmasm.cpp:
+    (JSC::testCagePreservesPACFailureBit):
+    * dfg/DFGSpeculativeJIT.cpp:
+    (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
+    * ftl/FTLLowerDFGToB3.cpp:
+    (JSC::FTL::DFG::LowerDFGToB3::caged):
+    * jit/AssemblyHelpers.h:
+    (JSC::AssemblyHelpers::cageConditionally):
+    * llint/LowLevelInterpreter64.asm:
+    * runtime/JSCConfig.h:
+    (JSC::Config::isPermanentlyFrozen):
+    
+    Source/WTF:
+    
+    We now think of the various Config records as being allocated from parts of a
+    WebConfig::g_config buffer.  WTF::Config will manage the mechanics of freezing
+    that buffer.  And the JSC VM is still the determiner of if/when to freeze the
+    buffer, and it will do this at the end of the construction of the very first
+    VM instance (as before).
+    
+    Gigacage::Config reserves space in WebConfig::g_config.
+    WTF::Config will honor that reservation and place itself after that.
+    JSC::Config will continue to place itself at WTF::Config::spaceForExtensions.
+    
+    The upside of this approach this is that we can now share the same memory page
+    for all the Configs, and can freeze them in one go.
+    
+    The downside is that g_gigacageConfig, g_wtfConfig, and g_jscConfig now have to
+    be macros.  This results in some weirdness e.g. they are no longer qualified by
+    namespaces: referring to WTF::g_wtfConfig is now incorrect.
+    
+    * wtf/Gigacage.h:
+    (Gigacage::disablingPrimitiveGigacageIsForbidden):
+    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+    * wtf/WTFConfig.cpp:
+    (WTF::Config::permanentlyFreeze):
+    * wtf/WTFConfig.h:
+    (): Deleted.
+    
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262434 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-06-02  Mark Lam  <mark....@apple.com>
+
+            Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
+            https://bugs.webkit.org/show_bug.cgi?id=212585
+            <rdar://problem/63812487>
+
+            Reviewed by Yusuke Suzuki.
+
+            We now think of the various Config records as being allocated from parts of a
+            WebConfig::g_config buffer.  WTF::Config will manage the mechanics of freezing
+            that buffer.  And the JSC VM is still the determiner of if/when to freeze the
+            buffer, and it will do this at the end of the construction of the very first
+            VM instance (as before).
+
+            Gigacage::Config reserves space in WebConfig::g_config.
+            WTF::Config will honor that reservation and place itself after that.
+            JSC::Config will continue to place itself at WTF::Config::spaceForExtensions.
+
+            The upside of this approach this is that we can now share the same memory page
+            for all the Configs, and can freeze them in one go.
+
+            The downside is that g_gigacageConfig, g_wtfConfig, and g_jscConfig now have to
+            be macros.  This results in some weirdness e.g. they are no longer qualified by
+            namespaces: referring to WTF::g_wtfConfig is now incorrect.
+
+            * wtf/Gigacage.h:
+            (Gigacage::disablingPrimitiveGigacageIsForbidden):
+            (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+            (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+            (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+            * wtf/WTFConfig.cpp:
+            (WTF::Config::permanentlyFreeze):
+            * wtf/WTFConfig.h:
+            (): Deleted.
+
+2020-06-02  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r262356. rdar://problem/63891520
 
     Change JSC::Config to use storage in WTF::Config instead of its own.

Modified: branches/safari-610.1.15-branch/Source/WTF/wtf/Gigacage.h (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/WTF/wtf/Gigacage.h	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/WTF/wtf/Gigacage.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -51,10 +51,6 @@
 
 inline void forbidDisablingPrimitiveGigacage() { }
 
-inline bool isDisablingPrimitiveGigacageForbidden() { return false; }
-inline bool isPrimitiveGigacagePermanentlyEnabled() { return false; }
-inline bool canPrimitiveGigacageBeDisabled() { return true; }
-
 ALWAYS_INLINE const char* name(Kind kind)
 {
     switch (kind) {
@@ -70,6 +66,7 @@
 }
 
 ALWAYS_INLINE bool contains(const void*) { return false; }
+ALWAYS_INLINE bool disablingPrimitiveGigacageIsForbidden() { return false; }
 ALWAYS_INLINE bool isEnabled(Kind) { return false; }
 ALWAYS_INLINE size_t mask(Kind) { return 0; }
 

Modified: branches/safari-610.1.15-branch/Source/WTF/wtf/WTFConfig.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/WTF/wtf/WTFConfig.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/WTF/wtf/WTFConfig.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include <wtf/WTFConfig.h>
 
+#include <wtf/Gigacage.h>
 #include <wtf/Lock.h>
 #include <wtf/StdLibExtras.h>
 
@@ -35,10 +36,14 @@
 #include <sys/mman.h>
 #endif
 
+namespace WebConfig {
+
+alignas(WTF::ConfigSizeToProtect) Slot g_config[WTF::ConfigSizeToProtect / sizeof(Slot)];
+
+} // namespace WebConfig
+
 namespace WTF {
 
-alignas(ConfigSizeToProtect) WTF_EXPORT_PRIVATE Config g_wtfConfig;
-
 void Config::permanentlyFreeze()
 {
     static Lock configLock;
@@ -46,8 +51,12 @@
 
     RELEASE_ASSERT(roundUpToMultipleOf(pageSize(), ConfigSizeToProtect) == ConfigSizeToProtect);
 
-    if (!g_wtfConfig.isPermanentlyFrozen)
+    if (!g_wtfConfig.isPermanentlyFrozen) {
         g_wtfConfig.isPermanentlyFrozen = true;
+#if GIGACAGE_ENABLED
+        g_gigacageConfig.isPermanentlyFrozen = true;
+#endif
+    }
 
     int result = 0;
 #if OS(DARWIN)
@@ -57,9 +66,9 @@
     };
 
     // There's no going back now!
-    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_wtfConfig), ConfigSizeToProtect, DisallowPermissionChangesAfterThis, VM_PROT_READ);
+    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&WebConfig::g_config), ConfigSizeToProtect, DisallowPermissionChangesAfterThis, VM_PROT_READ);
 #elif OS(LINUX)
-    result = mprotect(&g_wtfConfig, ConfigSizeToProtect, PROT_READ);
+    result = mprotect(&WebConfig::g_config, ConfigSizeToProtect, PROT_READ);
 #elif OS(WINDOWS)
     // FIXME: Implement equivalent, maybe with VirtualProtect.
     // Also need to fix WebKitTestRunner.

Modified: branches/safari-610.1.15-branch/Source/WTF/wtf/WTFConfig.h (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/WTF/wtf/WTFConfig.h	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/WTF/wtf/WTFConfig.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -33,6 +33,22 @@
 #include <wtf/StdLibExtras.h>
 #include <wtf/threads/Signals.h>
 
+#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
+namespace Gigacage {
+constexpr size_t reservedSlotsForGigacageConfig = 0;
+constexpr size_t reservedBytesForGigacageConfig = 0;
+}
+#else
+#include <bmalloc/GigacageConfig.h>
+#endif
+
+namespace WebConfig {
+
+using Slot = uint64_t;
+extern "C" WTF_EXPORT_PRIVATE Slot g_config[];
+
+} // namespace WebConfig
+
 namespace WTF {
 
 constexpr size_t ConfigSizeToProtect = CeilingOnPageSize;
@@ -45,29 +61,32 @@
         ~AssertNotFrozenScope();
     };
 
-    union {
-        struct {
-            // All the fields in this struct should be chosen such that their
-            // initial value is 0 / null / falsy because Config is instantiated
-            // as a global singleton.
+    // All the fields in this struct should be chosen such that their
+    // initial value is 0 / null / falsy because Config is instantiated
+    // as a global singleton.
 
-            bool isPermanentlyFrozen;
+    bool isPermanentlyFrozen;
 
 #if USE(PTHREADS) && HAVE(MACHINE_CONTEXT)
-            SignalHandlers signalHandlers;
+    SignalHandlers signalHandlers;
 #endif
-            PtrTagLookup* ptrTagLookupHead;
+    PtrTagLookup* ptrTagLookupHead;
 
-            uint64_t spaceForExtensions[1];
-        };
-        char ensureSize[ConfigSizeToProtect];
-    };
+    uint64_t spaceForExtensions[1];
 };
 
-extern "C" alignas(ConfigSizeToProtect) WTF_EXPORT_PRIVATE Config g_wtfConfig;
+constexpr size_t startSlotOfWTFConfig = Gigacage::reservedSlotsForGigacageConfig;
+constexpr size_t startOffsetOfWTFConfig = startSlotOfWTFConfig * sizeof(WebConfig::Slot);
 
-static_assert(sizeof(Config) == ConfigSizeToProtect);
+constexpr size_t offsetOfWTFConfigExtension = startOffsetOfWTFConfig + offsetof(WTF::Config, spaceForExtensions);
 
+constexpr size_t alignmentOfWTFConfig = std::alignment_of<WTF::Config>::value;
+
+static_assert(Gigacage::reservedBytesForGigacageConfig + sizeof(WTF::Config) <= ConfigSizeToProtect);
+static_assert(roundUpToMultipleOf<alignmentOfWTFConfig>(startOffsetOfWTFConfig) == startOffsetOfWTFConfig);
+
+#define g_wtfConfig (*bitwise_cast<WTF::Config*>(&WebConfig::g_config[WTF::startSlotOfWTFConfig]))
+
 ALWAYS_INLINE Config::AssertNotFrozenScope::AssertNotFrozenScope()
 {
     RELEASE_ASSERT(!g_wtfConfig.isPermanentlyFrozen);

Modified: branches/safari-610.1.15-branch/Source/bmalloc/CMakeLists.txt (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/CMakeLists.txt	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/CMakeLists.txt	2020-06-02 21:58:25 UTC (rev 262450)
@@ -69,6 +69,8 @@
     bmalloc/FreeList.h
     bmalloc/FreeListInlines.h
     bmalloc/Gigacage.h
+    bmalloc/GigacageConfig.h
+    bmalloc/GigacageKind.h
     bmalloc/Heap.h
     bmalloc/HeapConstants.h
     bmalloc/HeapKind.h

Modified: branches/safari-610.1.15-branch/Source/bmalloc/ChangeLog (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/ChangeLog	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/ChangeLog	2020-06-02 21:58:25 UTC (rev 262450)
@@ -1,3 +1,278 @@
+2020-06-02  Alan Coon  <alanc...@apple.com>
+
+        Cherry-pick r262434. rdar://problem/63891520
+
+    Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
+    https://bugs.webkit.org/show_bug.cgi?id=212585
+    <rdar://problem/63812487>
+    
+    Reviewed by Yusuke Suzuki.
+    
+    Source/bmalloc:
+    
+    1. Gigacage::Config now reserves and expect space to be available in an external
+       WebConfig::g_config buffer.  Gigacage does not allocate that buffer.
+    
+    2. Moved Gigacage::Config to GigacageConfig.h.
+       This allows WTFConfig.h to include GigacageConfig.h instead of all of Gigacage.h.
+    
+    3. Moved Gigacage::Kind to GigacageKind.h.
+       Otherwise, Gigacage::Kind would need to move to GigacageConfig.h which is a
+       weird place to put it.
+    
+    4. Removed freezeGigacageConfig(), unfreezeGigacageConfig(), and
+       permanentlyFreezeGigacageConfig().
+    
+       It is no longer possible to temporarily freeze and unfreeze the Gigacage::Config
+       because it now share the same memory page with higher level Configs.
+    
+       permanentlyFreezeGigacageConfig() is no longer needed because it is subsumed
+       by WTF::Config::permanentlyFreeze(), which will freeze the entire WebConfig::g_config
+       buffer.
+    
+       One difference in behavior here is that Gigacage::Config data used to be permanently
+       frozen as soon as forbidDisablingPrimitiveGigacage() is called.  Now, it isn't
+       permanently frozen until the end of the construction of the first JSC::VM instance
+       in the process (just like the other Config records).  This still guarantees that
+       it is frozen before any JS script can run.
+    
+    5. Previously, disablePrimitiveGigacage() works by nullifying the Primitive gigacage
+       base pointer.  We can no longer do that because the base pointer will be frozen
+       on VM instantiation.  Instead, if not forbidden, we now disable the Primitive
+       gigacage by setting a disablePrimitiveGigacageRequested bool variable that is
+       not frozen in the Gigacage::Config.
+    
+       To check if the Primitive gigacage is enabled, the LLInt, AssemblyHelpers::cageConditionally(),
+       and runtime functions will check the following conditions:
+    
+           g_gigacageConfig.basePtr(Primitive) &&
+               (disablingPrimitiveGigacageIsForbidden() || disableNotRequestedForPrimitiveGigacage())
+    
+           The base pointer being null means the gigacage was never set up.
+    
+           If disablingPrimitiveGigacageIsForbidden() is true, then we don't care
+           whether a disable request has been received.
+    
+           Otherwise, the gigacage is only enabled if it has been set up, and a
+           disable request has not been received.
+    
+           Note that the first 2 terms are frozen in the Gigacage::Config.  Only the
+           last term is a runtime variable.  If disabling is forbidden, then the
+           runtime variable never comes into play.
+    
+       The FTL does not rely on a runtime check for whether the Primitive gigacage is
+       enabled or not.  Instead, it relies on a watchpoint to handle this.  So, it
+       just works, and there's no performance penalty with adding the 2 extra terms
+       to check.
+    
+       Note also that the jsc shell and the WebProcess will forbid disabling of the
+       Primitive gigacage.  This means the AssemblyHelpers::cageConditionally() will
+       also not generate the runtime checks for the 2 extra terms.
+    
+       Only the LLInt and runtime functions will have to do work to check the 2 extra
+       terms.  But because these are not in perf critical paths, this is ok.
+    
+       Note that we're deliberately gating the disablePrimitiveGigacageRequested
+       variable check on disablingPrimitiveGigacageIsForbidden though, logically, the
+       isEnable check does not really depend on whether disabling is forbidden or not.
+       We do this because disablingPrimitiveGigacageIsForbidden is frozen in the Config,
+       and it is, therefore, a stronger guarantee of correctness whereas the variable
+       can be corrupted.
+    
+    6. Replaced isDisablingPrimitiveGigacageForbidden(), canPrimitiveGigacageBeDisabled(),
+       and isPrimitiveGigacagePermanentlyEnabled() with disablingPrimitiveGigacageIsForbidden().
+    
+    * CMakeLists.txt:
+    * bmalloc.xcodeproj/project.pbxproj:
+    * bmalloc/Gigacage.cpp:
+    (Gigacage::ensureGigacage):
+    (Gigacage::disablePrimitiveGigacage):
+    (Gigacage::forbidDisablingPrimitiveGigacage):
+    (Gigacage::bmalloc::freezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::unfreezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::permanentlyFreezeGigacageConfig): Deleted.
+    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope): Deleted.
+    (Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope): Deleted.
+    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+    * bmalloc/Gigacage.h:
+    (Gigacage::disablingPrimitiveGigacageIsForbidden):
+    (Gigacage::disableNotRequestedForPrimitiveGigacage):
+    (Gigacage::isEnabled):
+    (Gigacage::basePtr):
+    (Gigacage::caged):
+    (Gigacage::forbidDisablingPrimitiveGigacage):
+    (): Deleted.
+    (Gigacage::Config::basePtr const): Deleted.
+    (Gigacage::Config::setBasePtr): Deleted.
+    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+    * bmalloc/GigacageConfig.h: Added.
+    (Gigacage::Config::basePtr const):
+    (Gigacage::Config::setBasePtr):
+    * bmalloc/GigacageKind.h: Added.
+    * bmalloc/Heap.cpp:
+    (bmalloc::Heap::usingGigacage):
+    * bmalloc/mbmalloc.cpp:
+    
+    Source/_javascript_Core:
+    
+    * assembler/testmasm.cpp:
+    (JSC::testCagePreservesPACFailureBit):
+    * dfg/DFGSpeculativeJIT.cpp:
+    (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
+    * ftl/FTLLowerDFGToB3.cpp:
+    (JSC::FTL::DFG::LowerDFGToB3::caged):
+    * jit/AssemblyHelpers.h:
+    (JSC::AssemblyHelpers::cageConditionally):
+    * llint/LowLevelInterpreter64.asm:
+    * runtime/JSCConfig.h:
+    (JSC::Config::isPermanentlyFrozen):
+    
+    Source/WTF:
+    
+    We now think of the various Config records as being allocated from parts of a
+    WebConfig::g_config buffer.  WTF::Config will manage the mechanics of freezing
+    that buffer.  And the JSC VM is still the determiner of if/when to freeze the
+    buffer, and it will do this at the end of the construction of the very first
+    VM instance (as before).
+    
+    Gigacage::Config reserves space in WebConfig::g_config.
+    WTF::Config will honor that reservation and place itself after that.
+    JSC::Config will continue to place itself at WTF::Config::spaceForExtensions.
+    
+    The upside of this approach this is that we can now share the same memory page
+    for all the Configs, and can freeze them in one go.
+    
+    The downside is that g_gigacageConfig, g_wtfConfig, and g_jscConfig now have to
+    be macros.  This results in some weirdness e.g. they are no longer qualified by
+    namespaces: referring to WTF::g_wtfConfig is now incorrect.
+    
+    * wtf/Gigacage.h:
+    (Gigacage::disablingPrimitiveGigacageIsForbidden):
+    (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+    (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+    (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+    * wtf/WTFConfig.cpp:
+    (WTF::Config::permanentlyFreeze):
+    * wtf/WTFConfig.h:
+    (): Deleted.
+    
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262434 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-06-02  Mark Lam  <mark....@apple.com>
+
+            Change Gigacage::Config to use storage in WebConfig::g_config instead of its own.
+            https://bugs.webkit.org/show_bug.cgi?id=212585
+            <rdar://problem/63812487>
+
+            Reviewed by Yusuke Suzuki.
+
+            1. Gigacage::Config now reserves and expect space to be available in an external
+               WebConfig::g_config buffer.  Gigacage does not allocate that buffer.
+
+            2. Moved Gigacage::Config to GigacageConfig.h.
+               This allows WTFConfig.h to include GigacageConfig.h instead of all of Gigacage.h.
+
+            3. Moved Gigacage::Kind to GigacageKind.h.
+               Otherwise, Gigacage::Kind would need to move to GigacageConfig.h which is a
+               weird place to put it.
+
+            4. Removed freezeGigacageConfig(), unfreezeGigacageConfig(), and
+               permanentlyFreezeGigacageConfig().
+
+               It is no longer possible to temporarily freeze and unfreeze the Gigacage::Config
+               because it now share the same memory page with higher level Configs.
+
+               permanentlyFreezeGigacageConfig() is no longer needed because it is subsumed
+               by WTF::Config::permanentlyFreeze(), which will freeze the entire WebConfig::g_config
+               buffer.
+
+               One difference in behavior here is that Gigacage::Config data used to be permanently
+               frozen as soon as forbidDisablingPrimitiveGigacage() is called.  Now, it isn't
+               permanently frozen until the end of the construction of the first JSC::VM instance
+               in the process (just like the other Config records).  This still guarantees that
+               it is frozen before any JS script can run.
+
+            5. Previously, disablePrimitiveGigacage() works by nullifying the Primitive gigacage
+               base pointer.  We can no longer do that because the base pointer will be frozen
+               on VM instantiation.  Instead, if not forbidden, we now disable the Primitive
+               gigacage by setting a disablePrimitiveGigacageRequested bool variable that is
+               not frozen in the Gigacage::Config.
+
+               To check if the Primitive gigacage is enabled, the LLInt, AssemblyHelpers::cageConditionally(),
+               and runtime functions will check the following conditions:
+
+                   g_gigacageConfig.basePtr(Primitive) &&
+                       (disablingPrimitiveGigacageIsForbidden() || disableNotRequestedForPrimitiveGigacage())
+
+                   The base pointer being null means the gigacage was never set up.
+
+                   If disablingPrimitiveGigacageIsForbidden() is true, then we don't care
+                   whether a disable request has been received.
+
+                   Otherwise, the gigacage is only enabled if it has been set up, and a
+                   disable request has not been received.
+
+                   Note that the first 2 terms are frozen in the Gigacage::Config.  Only the
+                   last term is a runtime variable.  If disabling is forbidden, then the
+                   runtime variable never comes into play.
+
+               The FTL does not rely on a runtime check for whether the Primitive gigacage is
+               enabled or not.  Instead, it relies on a watchpoint to handle this.  So, it
+               just works, and there's no performance penalty with adding the 2 extra terms
+               to check.
+
+               Note also that the jsc shell and the WebProcess will forbid disabling of the
+               Primitive gigacage.  This means the AssemblyHelpers::cageConditionally() will
+               also not generate the runtime checks for the 2 extra terms.
+
+               Only the LLInt and runtime functions will have to do work to check the 2 extra
+               terms.  But because these are not in perf critical paths, this is ok.
+
+               Note that we're deliberately gating the disablePrimitiveGigacageRequested
+               variable check on disablingPrimitiveGigacageIsForbidden though, logically, the
+               isEnable check does not really depend on whether disabling is forbidden or not.
+               We do this because disablingPrimitiveGigacageIsForbidden is frozen in the Config,
+               and it is, therefore, a stronger guarantee of correctness whereas the variable
+               can be corrupted.
+
+            6. Replaced isDisablingPrimitiveGigacageForbidden(), canPrimitiveGigacageBeDisabled(),
+               and isPrimitiveGigacagePermanentlyEnabled() with disablingPrimitiveGigacageIsForbidden().
+
+            * CMakeLists.txt:
+            * bmalloc.xcodeproj/project.pbxproj:
+            * bmalloc/Gigacage.cpp:
+            (Gigacage::ensureGigacage):
+            (Gigacage::disablePrimitiveGigacage):
+            (Gigacage::forbidDisablingPrimitiveGigacage):
+            (Gigacage::bmalloc::freezeGigacageConfig): Deleted.
+            (Gigacage::bmalloc::unfreezeGigacageConfig): Deleted.
+            (Gigacage::bmalloc::permanentlyFreezeGigacageConfig): Deleted.
+            (Gigacage::bmalloc::UnfreezeGigacageConfigScope::UnfreezeGigacageConfigScope): Deleted.
+            (Gigacage::bmalloc::UnfreezeGigacageConfigScope::~UnfreezeGigacageConfigScope): Deleted.
+            (Gigacage::isDisablingPrimitiveGigacageForbidden): Deleted.
+            * bmalloc/Gigacage.h:
+            (Gigacage::disablingPrimitiveGigacageIsForbidden):
+            (Gigacage::disableNotRequestedForPrimitiveGigacage):
+            (Gigacage::isEnabled):
+            (Gigacage::basePtr):
+            (Gigacage::caged):
+            (Gigacage::forbidDisablingPrimitiveGigacage):
+            (): Deleted.
+            (Gigacage::Config::basePtr const): Deleted.
+            (Gigacage::Config::setBasePtr): Deleted.
+            (Gigacage::isPrimitiveGigacagePermanentlyEnabled): Deleted.
+            (Gigacage::canPrimitiveGigacageBeDisabled): Deleted.
+            * bmalloc/GigacageConfig.h: Added.
+            (Gigacage::Config::basePtr const):
+            (Gigacage::Config::setBasePtr):
+            * bmalloc/GigacageKind.h: Added.
+            * bmalloc/Heap.cpp:
+            (bmalloc::Heap::usingGigacage):
+            * bmalloc/mbmalloc.cpp:
+
 2020-05-18  Mark Lam  <mark....@apple.com>
 
         Implement a faster findBitInWord() using the hardware ctz instruction.

Modified: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Gigacage.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Gigacage.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Gigacage.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -56,7 +56,7 @@
     void* argument { nullptr };
 };
 
-}
+} // namespace Gigacage
 
 namespace bmalloc {
 
@@ -79,75 +79,12 @@
 // If this were less than 32GB, those OOB accesses could reach outside of the cage.
 constexpr size_t gigacageRunway = 32llu * bmalloc::Sizes::GB;
 
-alignas(configSizeToProtect) Config g_gigacageConfig;
+bool disablePrimitiveGigacageRequested = false;
 
 using namespace bmalloc;
 
 namespace {
 
-#if BOS(DARWIN)
-enum {
-    AllowPermissionChangesAfterThis = false,
-    DisallowPermissionChangesAfterThis = true
-};
-#endif
-
-static void freezeGigacageConfig()
-{
-    int result;
-#if BOS(DARWIN)
-    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_gigacageConfig), configSizeToProtect, AllowPermissionChangesAfterThis, VM_PROT_READ);
-#else
-    result = mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ);
-#endif
-    RELEASE_BASSERT(!result);
-}
-
-static void unfreezeGigacageConfig()
-{
-    RELEASE_BASSERT(!g_gigacageConfig.isPermanentlyFrozen);
-    int result;
-#if BOS(DARWIN)
-    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_gigacageConfig), configSizeToProtect, AllowPermissionChangesAfterThis, VM_PROT_READ | VM_PROT_WRITE);
-#else
-    result = mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ | PROT_WRITE);
-#endif
-    RELEASE_BASSERT(!result);
-}
-
-static void permanentlyFreezeGigacageConfig()
-{
-    static Mutex configLock;
-    LockHolder locking(configLock);
-
-    if (!g_gigacageConfig.isPermanentlyFrozen) {
-        unfreezeGigacageConfig();
-        g_gigacageConfig.isPermanentlyFrozen = true;
-    }
-
-    // There's no going back now!
-    int result;
-#if BOS(DARWIN)
-    result = vm_protect(mach_task_self(), reinterpret_cast<vm_address_t>(&g_gigacageConfig), configSizeToProtect, DisallowPermissionChangesAfterThis, VM_PROT_READ);
-#else
-    result = mprotect(&g_gigacageConfig, configSizeToProtect, PROT_READ);
-#endif
-    RELEASE_BASSERT(!result);
-}
-
-class UnfreezeGigacageConfigScope {
-public:
-    UnfreezeGigacageConfigScope()
-    {
-        unfreezeGigacageConfig();
-    }
-    
-    ~UnfreezeGigacageConfigScope()
-    {
-        freezeGigacageConfig();
-    }
-};
-
 size_t runwaySize(Kind kind)
 {
     switch (kind) {
@@ -240,7 +177,6 @@
             g_gigacageConfig.totalSize = totalSize;
             vmDeallocatePhysicalPages(base, totalSize);
             g_gigacageConfig.isEnabled = true;
-            freezeGigacageConfig();
         });
 }
 
@@ -250,9 +186,9 @@
         fprintf(stderr, "FATAL: Disabling Primitive gigacage is forbidden, but we don't want that in this process.\n");
 
     RELEASE_BASSERT(!g_gigacageConfig.disablingPrimitiveGigacageIsForbidden);
-    RELEASE_BASSERT(!g_gigacageConfig.isPermanentlyFrozen);
 
     ensureGigacage();
+    disablePrimitiveGigacageRequested = true;
     if (!g_gigacageConfig.basePtrs[Primitive]) {
         // It was never enabled. That means that we never even saved any callbacks. Or, we had already disabled
         // it before, and already called the callbacks.
@@ -264,8 +200,6 @@
     for (Callback& callback : callbacks.callbacks)
         callback.function(callback.argument);
     callbacks.callbacks.shrink(0);
-    UnfreezeGigacageConfigScope unfreezeScope;
-    g_gigacageConfig.basePtrs[Primitive] = nullptr;
 }
 
 void addPrimitiveDisableCallback(void (*function)(void*), void* argument)
@@ -312,19 +246,11 @@
     RELEASE_BASSERT(g_gigacageConfig.shouldBeEnabledHasBeenCalled
         && (GIGACAGE_ALLOCATION_CAN_FAIL || !g_gigacageConfig.shouldBeEnabled || verifyGigacageIsEnabled()));
 
-    if (!g_gigacageConfig.disablingPrimitiveGigacageIsForbidden) {
-        unfreezeGigacageConfig();
+    if (!g_gigacageConfig.disablingPrimitiveGigacageIsForbidden)
         g_gigacageConfig.disablingPrimitiveGigacageIsForbidden = true;
-    }
-    permanentlyFreezeGigacageConfig();
-    RELEASE_BASSERT(isDisablingPrimitiveGigacageForbidden());
+    RELEASE_BASSERT(disablingPrimitiveGigacageIsForbidden());
 }
 
-BNO_INLINE bool isDisablingPrimitiveGigacageForbidden()
-{
-    return g_gigacageConfig.disablingPrimitiveGigacageIsForbidden;
-}
-
 bool shouldBeEnabled()
 {
     static std::once_flag onceFlag;

Modified: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Gigacage.h (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Gigacage.h	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Gigacage.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,12 +25,13 @@
 
 #pragma once
 
-#include "Algorithm.h"
 #include "BAssert.h"
 #include "BExport.h"
 #include "BInline.h"
 #include "BPlatform.h"
+#include "GigacageConfig.h"
 #include "Sizes.h"
+#include "StdLibExtras.h"
 #include <cstddef>
 #include <inttypes.h>
 
@@ -44,12 +45,6 @@
 
 namespace Gigacage {
 
-enum Kind {
-    Primitive,
-    JSValue,
-    NumberOfKinds
-};
-
 BINLINE const char* name(Kind kind)
 {
     switch (kind) {
@@ -66,8 +61,6 @@
 
 #if GIGACAGE_ENABLED
 
-constexpr size_t configSizeToProtect = 16 * bmalloc::Sizes::kB;
-
 #if BOS_EFFECTIVE_ADDRESS_WIDTH < 48
 constexpr size_t primitiveGigacageSize = 2 * bmalloc::Sizes::GB;
 constexpr size_t jsValueGigacageSize = 2 * bmalloc::Sizes::GB;
@@ -97,51 +90,11 @@
 constexpr size_t primitiveGigacageMask = gigacageSizeToMask(primitiveGigacageSize);
 constexpr size_t jsValueGigacageMask = gigacageSizeToMask(jsValueGigacageSize);
 
-struct Config {
-    void* basePtr(Kind kind) const
-    {
-        RELEASE_BASSERT(kind < NumberOfKinds);
-        return basePtrs[kind];
-    }
-
-    void setBasePtr(Kind kind, void* ptr)
-    {
-        RELEASE_BASSERT(kind < NumberOfKinds);
-        basePtrs[kind] = ptr;
-    }
-
-    union {
-        struct {
-            // All the fields in this struct should be chosen such that their
-            // initial value is 0 / null / falsy because Config is instantiated
-            // as a global singleton.
-
-            bool isEnabled;
-            bool isPermanentlyFrozen;
-            bool disablingPrimitiveGigacageIsForbidden;
-            bool shouldBeEnabled;
-
-            // We would like to just put the std::once_flag for these functions
-            // here, but we can't because std::once_flag has a implicitly-deleted
-            // default constructor. So, we use a boolean instead.
-            bool shouldBeEnabledHasBeenCalled;
-            bool ensureGigacageHasBeenCalled;
-
-            void* start;
-            size_t totalSize;
-            void* basePtrs[NumberOfKinds];
-        };
-        char ensureSize[configSizeToProtect];
-    };
-};
-static_assert(sizeof(Config) == configSizeToProtect, "Gigacage Config must fit in configSizeToProtect");
-
-extern "C" alignas(configSizeToProtect) BEXPORT Config g_gigacageConfig;
-
 // These constants are needed by the LLInt.
 constexpr ptrdiff_t offsetOfPrimitiveGigacageBasePtr = Kind::Primitive * sizeof(void*);
 constexpr ptrdiff_t offsetOfJSValueGigacageBasePtr = Kind::JSValue * sizeof(void*);
 
+extern "C" BEXPORT bool disablePrimitiveGigacageRequested;
 
 BINLINE bool isEnabled() { return g_gigacageConfig.isEnabled; }
 
@@ -155,12 +108,26 @@
 
 BEXPORT void forbidDisablingPrimitiveGigacage();
 
-BEXPORT bool isDisablingPrimitiveGigacageForbidden();
-inline bool isPrimitiveGigacagePermanentlyEnabled() { return isDisablingPrimitiveGigacageForbidden(); }
-inline bool canPrimitiveGigacageBeDisabled() { return !isDisablingPrimitiveGigacageForbidden(); }
+BINLINE bool disablingPrimitiveGigacageIsForbidden()
+{
+    return g_gigacageConfig.disablingPrimitiveGigacageIsForbidden;
+}
 
+BINLINE bool disableNotRequestedForPrimitiveGigacage()
+{
+    return !disablePrimitiveGigacageRequested;
+}
+
+BINLINE bool isEnabled(Kind kind)
+{
+    if (kind == Primitive)
+        return g_gigacageConfig.basePtr(Primitive) && (disablingPrimitiveGigacageIsForbidden() || disableNotRequestedForPrimitiveGigacage());
+    return g_gigacageConfig.basePtr(kind);
+}
+
 BINLINE void* basePtr(Kind kind)
 {
+    BASSERT(isEnabled(kind));
     return g_gigacageConfig.basePtr(kind);
 }
 
@@ -170,11 +137,6 @@
     return &g_gigacageConfig.basePtrs[kind];
 }
 
-BINLINE bool isEnabled(Kind kind)
-{
-    return !!g_gigacageConfig.basePtr(kind);
-}
-
 BINLINE size_t size(Kind kind)
 {
     switch (kind) {
@@ -210,9 +172,9 @@
 BINLINE T* caged(Kind kind, T* ptr)
 {
     BASSERT(ptr);
-    void* gigacageBasePtr = g_gigacageConfig.basePtr(kind);
-    if (!gigacageBasePtr)
+    if (!isEnabled(kind))
         return ptr;
+    void* gigacageBasePtr = basePtr(kind);
     return reinterpret_cast<T*>(
         reinterpret_cast<uintptr_t>(gigacageBasePtr) + (
             reinterpret_cast<uintptr_t>(ptr) & mask(kind)));
@@ -251,6 +213,7 @@
 BINLINE size_t size(Kind) { BCRASH(); return 0; }
 BINLINE void ensureGigacage() { }
 BINLINE bool contains(const void*) { return false; }
+BINLINE bool disablingPrimitiveGigacageIsForbidden() { return false; }
 BINLINE bool isEnabled() { return false; }
 BINLINE bool isCaged(Kind, const void*) { return true; }
 BINLINE bool isEnabled(Kind) { return false; }
@@ -257,7 +220,6 @@
 template<typename T> BINLINE T* caged(Kind, T* ptr) { return ptr; }
 template<typename T> BINLINE T* cagedMayBeNull(Kind, T* ptr) { return ptr; }
 BINLINE void forbidDisablingPrimitiveGigacage() { }
-BINLINE bool canPrimitiveGigacageBeDisabled() { return false; }
 BINLINE void disablePrimitiveGigacage() { }
 BINLINE void addPrimitiveDisableCallback(void (*)(void*), void*) { }
 BINLINE void removePrimitiveDisableCallback(void (*)(void*), void*) { }

Added: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/GigacageConfig.h (0 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/GigacageConfig.h	                        (rev 0)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/GigacageConfig.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Algorithm.h"
+#include "GigacageKind.h"
+#include "StdLibExtras.h"
+#include <inttypes.h>
+
+namespace WebConfig {
+
+using Slot = uint64_t;
+extern "C" Slot g_config[];
+
+} // namespace WebConfig
+
+namespace Gigacage {
+
+struct Config {
+    void* basePtr(Kind kind) const
+    {
+        RELEASE_BASSERT(kind < NumberOfKinds);
+        return basePtrs[kind];
+    }
+
+    void setBasePtr(Kind kind, void* ptr)
+    {
+        RELEASE_BASSERT(kind < NumberOfKinds);
+        basePtrs[kind] = ptr;
+    }
+
+    // All the fields in this struct should be chosen such that their
+    // initial value is 0 / null / falsy because Config is instantiated
+    // as a global singleton.
+
+    bool isPermanentlyFrozen; // Will be set by the client if the Config gets frozen.
+    bool isEnabled;
+    bool disablingPrimitiveGigacageIsForbidden;
+    bool shouldBeEnabled;
+
+    // We would like to just put the std::once_flag for these functions
+    // here, but we can't because std::once_flag has a implicitly-deleted
+    // default constructor. So, we use a boolean instead.
+    bool shouldBeEnabledHasBeenCalled;
+    bool ensureGigacageHasBeenCalled;
+
+    void* start;
+    size_t totalSize;
+    void* basePtrs[NumberOfKinds];
+};
+
+constexpr size_t startSlotOfGigacageConfig = 0;
+constexpr size_t startOffsetOfGigacageConfig = startSlotOfGigacageConfig * sizeof(WebConfig::Slot);
+
+constexpr size_t reservedSlotsForGigacageConfig = 6;
+constexpr size_t reservedBytesForGigacageConfig = reservedSlotsForGigacageConfig * sizeof(WebConfig::Slot);
+
+constexpr size_t alignmentOfGigacageConfig = std::alignment_of<Gigacage::Config>::value;
+
+static_assert(sizeof(Gigacage::Config) <= reservedBytesForGigacageConfig);
+static_assert(bmalloc::roundUpToMultipleOf<alignmentOfGigacageConfig>(startOffsetOfGigacageConfig) == startOffsetOfGigacageConfig);
+
+#define g_gigacageConfig (*bmalloc::bitwise_cast<Gigacage::Config*>(&WebConfig::g_config[Gigacage::startSlotOfGigacageConfig]))
+
+} // namespace Gigacage

Copied: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/GigacageKind.h (from rev 262449, branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/mbmalloc.cpp) (0 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/GigacageKind.h	                        (rev 0)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/GigacageKind.h	2020-06-02 21:58:25 UTC (rev 262450)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace Gigacage {
+
+enum Kind {
+    Primitive,
+    JSValue,
+    NumberOfKinds
+};
+
+} // namespace Gigacage

Modified: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Heap.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Heap.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/Heap.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -56,12 +56,13 @@
     Gigacage::ensureGigacage();
 #if GIGACAGE_ENABLED
     if (usingGigacage()) {
-        RELEASE_BASSERT(gigacageBasePtr());
+        void* gigacageBasePtr = this->gigacageBasePtr();
+        RELEASE_BASSERT(gigacageBasePtr);
         uint64_t random[2];
         cryptoRandom(reinterpret_cast<unsigned char*>(random), sizeof(random));
         size_t size = roundDownToMultipleOf(vmPageSize(), gigacageSize() - (random[0] % Gigacage::maximumCageSizeReductionForSlide));
         ptrdiff_t offset = roundDownToMultipleOf(vmPageSize(), random[1] % (gigacageSize() - size));
-        void* base = reinterpret_cast<unsigned char*>(gigacageBasePtr()) + offset;
+        void* base = reinterpret_cast<unsigned char*>(gigacageBasePtr) + offset;
         m_largeFree.add(LargeRange(base, size, 0, 0));
     }
 #endif
@@ -71,7 +72,7 @@
 
 bool Heap::usingGigacage()
 {
-    return isGigacage(m_kind) && gigacageBasePtr();
+    return isGigacage(m_kind) && Gigacage::isEnabled(gigacageKind(m_kind));
 }
 
 void* Heap::gigacageBasePtr()

Modified: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/mbmalloc.cpp (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/mbmalloc.cpp	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc/mbmalloc.cpp	2020-06-02 21:58:25 UTC (rev 262450)
@@ -26,7 +26,16 @@
 #include "bmalloc.h"
 
 #include "BExport.h"
+#include "GigacageConfig.h"
 
+namespace WebConfig {
+
+constexpr size_t ConfigSizeToProtect = 16 * bmalloc::Sizes::kB;
+
+alignas(ConfigSizeToProtect) BEXPORT Slot g_config[ConfigSizeToProtect / sizeof(Slot)];
+
+} // namespace WebConfig
+
 extern "C" {
 
 BEXPORT void* mbmalloc(size_t);

Modified: branches/safari-610.1.15-branch/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj (262449 => 262450)


--- branches/safari-610.1.15-branch/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj	2020-06-02 21:58:20 UTC (rev 262449)
+++ branches/safari-610.1.15-branch/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj	2020-06-02 21:58:25 UTC (rev 262450)
@@ -151,6 +151,8 @@
 		EB17D11123BFCD42002093A7 /* HeapConstants.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB17D11023BFC8C4002093A7 /* HeapConstants.cpp */; };
 		EB17D11223BFCD7A002093A7 /* HeapConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = EB17D10E23BE691D002093A7 /* HeapConstants.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE48BD3B2321E8D700F136D0 /* FailureAction.h in Headers */ = {isa = PBXBuildFile; fileRef = FE48BD3A2321E8CC00F136D0 /* FailureAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		FEC3A39324846A8100395B54 /* GigacageConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC3A39224846A6D00395B54 /* GigacageConfig.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		FEC3A395248471FE00395B54 /* GigacageKind.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC3A394248471FE00395B54 /* GigacageKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -307,6 +309,8 @@
 		EB17D10E23BE691D002093A7 /* HeapConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeapConstants.h; path = bmalloc/HeapConstants.h; sourceTree = "<group>"; };
 		EB17D11023BFC8C4002093A7 /* HeapConstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HeapConstants.cpp; path = bmalloc/HeapConstants.cpp; sourceTree = "<group>"; };
 		FE48BD3A2321E8CC00F136D0 /* FailureAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FailureAction.h; path = bmalloc/FailureAction.h; sourceTree = "<group>"; };
+		FEC3A39224846A6D00395B54 /* GigacageConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GigacageConfig.h; path = bmalloc/GigacageConfig.h; sourceTree = "<group>"; };
+		FEC3A394248471FE00395B54 /* GigacageKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GigacageKind.h; path = bmalloc/GigacageKind.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -486,6 +490,8 @@
 				FE48BD3A2321E8CC00F136D0 /* FailureAction.h */,
 				0F5BF14E1F22DEAF0029D91D /* Gigacage.cpp */,
 				0F5BF14C1F22B0C30029D91D /* Gigacage.h */,
+				FEC3A39224846A6D00395B54 /* GigacageConfig.h */,
+				FEC3A394248471FE00395B54 /* GigacageKind.h */,
 				14DA320E18875D9F007269E0 /* Heap.cpp */,
 				14DA320C18875B09007269E0 /* Heap.h */,
 				EB17D11023BFC8C4002093A7 /* HeapConstants.cpp */,
@@ -606,6 +612,7 @@
 				FE48BD3B2321E8D700F136D0 /* FailureAction.h in Headers */,
 				14DD78C818F48D7500950702 /* FixedVector.h in Headers */,
 				0F7EB8441F9541B000F1ABCB /* FreeList.h in Headers */,
+				FEC3A39324846A8100395B54 /* GigacageConfig.h in Headers */,
 				0F7EB8291F9541B000F1ABCB /* FreeListInlines.h in Headers */,
 				0F5BF14D1F22B0C30029D91D /* Gigacage.h in Headers */,
 				1400274918F89C1300115C97 /* Heap.h in Headers */,
@@ -654,6 +661,7 @@
 				E378A9E0246B68750029C2BB /* ObjectTypeTable.h in Headers */,
 				E328D84D23CEB38900545B18 /* Packed.h in Headers */,
 				0F5BF1491F22A8D80029D91D /* PerHeapKind.h in Headers */,
+				FEC3A395248471FE00395B54 /* GigacageKind.h in Headers */,
 				14DD78CB18F48D7500950702 /* PerProcess.h in Headers */,
 				14DD78CC18F48D7500950702 /* PerThread.h in Headers */,
 				795AB3C7206E0D340074FE76 /* PhysicalPageMap.h in Headers */,
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to