Changeset 240175 in webkit


Ignore:
Timestamp:
Jan 18, 2019 2:48:22 PM (5 years ago)
Author:
keith_miller@apple.com
Message:

Gigacages should start allocations from a slide
https://bugs.webkit.org/show_bug.cgi?id=193523

Reviewed by Mark Lam.

Source/bmalloc:

This patch makes it so that Gigacage Heaps slide the start of the
cage by some random amount. We still ensure that there is always
at least 4/2GB, on MacOS/iOS respectively, of VA space available
for allocation.

Also, this patch changes some macros into constants since macros
are the devil.

  • bmalloc/Gigacage.cpp:

(Gigacage::bmalloc::protectGigacageBasePtrs):
(Gigacage::bmalloc::unprotectGigacageBasePtrs):
(Gigacage::bmalloc::runwaySize):
(Gigacage::ensureGigacage):
(Gigacage::shouldBeEnabled):

  • bmalloc/Gigacage.h:

(Gigacage::name):
(Gigacage::gigacageSizeToMask):
(Gigacage::size):
(Gigacage::mask):
(Gigacage::basePtr):
(Gigacage::ensureGigacage):
(Gigacage::wasEnabled):
(Gigacage::isCaged):
(Gigacage::isEnabled):
(Gigacage::caged):
(Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled):
(Gigacage::canPrimitiveGigacageBeDisabled):
(Gigacage::disablePrimitiveGigacage):
(Gigacage::addPrimitiveDisableCallback):
(Gigacage::removePrimitiveDisableCallback):

  • bmalloc/Heap.cpp:

(bmalloc::Heap::Heap):

  • bmalloc/Sizes.h:

(bmalloc::Sizes::maskSizeClass):
(bmalloc::Sizes::maskObjectSize):
(bmalloc::Sizes::logSizeClass):
(bmalloc::Sizes::logObjectSize):
(bmalloc::Sizes::sizeClass):
(bmalloc::Sizes::objectSize):
(bmalloc::Sizes::pageSize):

Source/JavaScriptCore:

This patch changes some macros into constants since macros are the
devil.

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::caged):

  • llint/LowLevelInterpreter64.asm:

Source/WTF:

This patch changes some macros into constants since macros are the
devil.

  • wtf/Gigacage.cpp:
  • wtf/Gigacage.h:
Location:
trunk/Source
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r240171 r240175  
     12019-01-18  Keith Miller  <keith_miller@apple.com>
     2
     3        Gigacages should start allocations from a slide
     4        https://bugs.webkit.org/show_bug.cgi?id=193523
     5
     6        Reviewed by Mark Lam.
     7
     8        This patch changes some macros into constants since macros are the
     9        devil.
     10
     11        * ftl/FTLLowerDFGToB3.cpp:
     12        (JSC::FTL::DFG::LowerDFGToB3::caged):
     13        * llint/LowLevelInterpreter64.asm:
     14
    1152019-01-18  Matt Lewis  <jlewis3@apple.com>
    216
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r240114 r240175  
    1385313853    LValue caged(Gigacage::Kind kind, LValue ptr)
    1385413854    {
     13855#if GIGACAGE_ENABLED
    1385513856        if (!Gigacage::isEnabled(kind))
    1385613857            return ptr;
     
    1388113882        // https://bugs.webkit.org/show_bug.cgi?id=175493
    1388213883        return m_out.opaque(result);
     13884#else
     13885        return ptr;
     13886#endif
    1388313887    }
    1388413888   
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r240171 r240175  
    13161316    btiz t0, IsArray, .opGetByIdSlow
    13171317    btiz t0, IndexingShapeMask, .opGetByIdSlow
    1318     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t1)
     1318    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t3], t0, t1)
    13191319    loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
    13201320    bilt t0, 0, .opGetByIdSlow
     
    14391439    sxi2q t1, t1
    14401440
    1441     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, tagTypeNumber)
     1441    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t0], t3, tagTypeNumber)
    14421442    move TagTypeNumber, tagTypeNumber
    14431443
     
    15051505
    15061506    # We have Int8ArrayType.
    1507     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1507    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15081508    loadbs [t3, t1], t0
    15091509    finishIntGetByVal(t0, t1)
     
    15131513
    15141514    # We have Uint8ArrayType.
    1515     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1515    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15161516    loadb [t3, t1], t0
    15171517    finishIntGetByVal(t0, t1)
     
    15191519.opGetByValUint8ClampedArray:
    15201520    # We have Uint8ClampedArrayType.
    1521     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1521    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15221522    loadb [t3, t1], t0
    15231523    finishIntGetByVal(t0, t1)
     
    15281528
    15291529    # We have Int16ArrayType.
    1530     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1530    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15311531    loadhs [t3, t1, 2], t0
    15321532    finishIntGetByVal(t0, t1)
     
    15341534.opGetByValUint16Array:
    15351535    # We have Uint16ArrayType.
    1536     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1536    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15371537    loadh [t3, t1, 2], t0
    15381538    finishIntGetByVal(t0, t1)
     
    15461546
    15471547    # We have Int32ArrayType.
    1548     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1548    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15491549    loadi [t3, t1, 4], t0
    15501550    finishIntGetByVal(t0, t1)
     
    15521552.opGetByValUint32Array:
    15531553    # We have Uint32ArrayType.
    1554     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1554    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15551555    # This is the hardest part because of large unsigned values.
    15561556    loadi [t3, t1, 4], t0
     
    15641564
    15651565    # We have Float64ArrayType.
    1566     loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t2)
     1566    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr Gigacage::primitiveGigacageMask, JSArrayBufferView::m_vector[t0], t3, t2)
    15671567    loadd [t3, t1, 8], ft0
    15681568    bdnequn ft0, ft0, .opGetByValSlow
     
    16001600        loadConstantOrVariableInt32(size, t0, t3, .opPutByValSlow)
    16011601        sxi2q t3, t3
    1602         loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, tagTypeNumber)
     1602        loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr Gigacage::jsValueGigacageMask, JSObject::m_butterfly[t1], t0, tagTypeNumber)
    16031603        move TagTypeNumber, tagTypeNumber
    16041604        btinz t2, CopyOnWrite, .opPutByValSlow
  • trunk/Source/WTF/ChangeLog

    r240171 r240175  
     12019-01-18  Keith Miller  <keith_miller@apple.com>
     2
     3        Gigacages should start allocations from a slide
     4        https://bugs.webkit.org/show_bug.cgi?id=193523
     5
     6        Reviewed by Mark Lam.
     7
     8        This patch changes some macros into constants since macros are the
     9        devil.
     10
     11        * wtf/Gigacage.cpp:
     12        * wtf/Gigacage.h:
     13
    1142019-01-18  Matt Lewis  <jlewis3@apple.com>
    215
  • trunk/Source/WTF/wtf/Gigacage.cpp

    r240171 r240175  
    3333#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
    3434
    35 alignas(void*) char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE];
     35namespace Gigacage {
    3636
    37 namespace Gigacage {
     37alignas(void*) char g_gigacageBasePtrs[gigacageBasePtrsSize];
    3838
    3939void* tryMalloc(Kind, size_t size)
     
    6262
    6363} // namespace Gigacage
    64 #else
     64#else // defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
    6565#include <bmalloc/bmalloc.h>
    6666
  • trunk/Source/WTF/wtf/Gigacage.h

    r240171 r240175  
    2727
    2828#include <wtf/FastMalloc.h>
     29#include <wtf/StdLibExtras.h>
    2930
    3031#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
    3132#define GIGACAGE_ENABLED 0
    32 #define PRIMITIVE_GIGACAGE_MASK 0
    33 #define JSVALUE_GIGACAGE_MASK 0
    34 #define GIGACAGE_BASE_PTRS_SIZE 8192
    35 
    36 extern "C" {
    37 alignas(void*) extern WTF_EXPORT_PRIVATE char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE];
    38 }
    3933
    4034namespace Gigacage {
     35
     36const size_t primitiveGigacageMask = 0;
     37const size_t jsValueGigacageMask = 0;
     38const size_t gigacageBasePtrsSize = 8 * KB;
     39
     40extern "C" alignas(void*) WTF_EXPORT_PRIVATE char g_gigacageBasePtrs[gigacageBasePtrsSize];
    4141
    4242struct BasePtrs {
  • trunk/Source/bmalloc/ChangeLog

    r240171 r240175  
     12019-01-18  Keith Miller  <keith_miller@apple.com>
     2
     3        Gigacages should start allocations from a slide
     4        https://bugs.webkit.org/show_bug.cgi?id=193523
     5
     6        Reviewed by Mark Lam.
     7
     8        This patch makes it so that Gigacage Heaps slide the start of the
     9        cage by some random amount. We still ensure that there is always
     10        at least 4/2GB, on MacOS/iOS respectively, of VA space available
     11        for allocation.
     12
     13        Also, this patch changes some macros into constants since macros
     14        are the devil.
     15
     16        * bmalloc/Gigacage.cpp:
     17        (Gigacage::bmalloc::protectGigacageBasePtrs):
     18        (Gigacage::bmalloc::unprotectGigacageBasePtrs):
     19        (Gigacage::bmalloc::runwaySize):
     20        (Gigacage::ensureGigacage):
     21        (Gigacage::shouldBeEnabled):
     22        * bmalloc/Gigacage.h:
     23        (Gigacage::name):
     24        (Gigacage::gigacageSizeToMask):
     25        (Gigacage::size):
     26        (Gigacage::mask):
     27        (Gigacage::basePtr):
     28        (Gigacage::ensureGigacage):
     29        (Gigacage::wasEnabled):
     30        (Gigacage::isCaged):
     31        (Gigacage::isEnabled):
     32        (Gigacage::caged):
     33        (Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled):
     34        (Gigacage::canPrimitiveGigacageBeDisabled):
     35        (Gigacage::disablePrimitiveGigacage):
     36        (Gigacage::addPrimitiveDisableCallback):
     37        (Gigacage::removePrimitiveDisableCallback):
     38        * bmalloc/Heap.cpp:
     39        (bmalloc::Heap::Heap):
     40        * bmalloc/Sizes.h:
     41        (bmalloc::Sizes::maskSizeClass):
     42        (bmalloc::Sizes::maskObjectSize):
     43        (bmalloc::Sizes::logSizeClass):
     44        (bmalloc::Sizes::logObjectSize):
     45        (bmalloc::Sizes::sizeClass):
     46        (bmalloc::Sizes::objectSize):
     47        (bmalloc::Sizes::pageSize):
     48
    1492019-01-18  Matt Lewis  <jlewis3@apple.com>
    250
  • trunk/Source/bmalloc/bmalloc/Gigacage.cpp

    r240171 r240175  
    3636#include <mutex>
    3737
     38#if GIGACAGE_ENABLED
     39
     40namespace Gigacage {
     41
    3842// This is exactly 32GB because inside JSC, indexed accesses for arrays, typed arrays, etc,
    3943// use unsigned 32-bit ints as indices. The items those indices access are 8 bytes or less
     
    4145// bounds, the access is guaranteed to land somewhere else in the cage or inside the runway.
    4246// If this were less than 32GB, those OOB accesses could reach outside of the cage.
    43 #define GIGACAGE_RUNWAY (32llu * 1024 * 1024 * 1024)
     47constexpr size_t gigacageRunway = 32llu * 1024 * 1024 * 1024;
    4448
    4549// Note: g_gigacageBasePtrs[0] is reserved for storing the wasEnabled flag.
     
    4751// This is done so that the wasEnabled flag will also be protected along with the
    4852// gigacageBasePtrs.
    49 alignas(GIGACAGE_BASE_PTRS_SIZE) char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE];
     53alignas(gigacageBasePtrsSize) char g_gigacageBasePtrs[gigacageBasePtrsSize];
    5054
    5155using namespace bmalloc;
    52 
    53 namespace Gigacage {
    5456
    5557namespace {
     
    6264    // We might only get page size alignment, but that's also the minimum we need.
    6365    RELEASE_BASSERT(!(basePtrs & (vmPageSize() - 1)));
    64     mprotect(g_gigacageBasePtrs, GIGACAGE_BASE_PTRS_SIZE, PROT_READ);
     66    mprotect(g_gigacageBasePtrs, gigacageBasePtrsSize, PROT_READ);
    6567}
    6668
    6769void unprotectGigacageBasePtrs()
    6870{
    69     mprotect(g_gigacageBasePtrs, GIGACAGE_BASE_PTRS_SIZE, PROT_READ | PROT_WRITE);
     71    mprotect(g_gigacageBasePtrs, gigacageBasePtrsSize, PROT_READ | PROT_WRITE);
    7072}
    7173
     
    102104};
    103105
    104 #if GIGACAGE_ENABLED
    105106size_t runwaySize(Kind kind)
    106107{
     
    109110        RELEASE_BASSERT_NOT_REACHED();
    110111    case Kind::Primitive:
    111         return static_cast<size_t>(GIGACAGE_RUNWAY);
     112        return gigacageRunway;
    112113    case Kind::JSValue:
    113         return static_cast<size_t>(0);
    114     }
    115     return static_cast<size_t>(0);
    116 }
    117 #endif
     114        return 0;
     115    }
     116    return 0;
     117}
    118118
    119119} // anonymous namespace
     
    121121void ensureGigacage()
    122122{
    123 #if GIGACAGE_ENABLED
    124123    static std::once_flag onceFlag;
    125124    std::call_once(
     
    190189            protectGigacageBasePtrs();
    191190        });
    192 #endif // GIGACAGE_ENABLED
    193191}
    194192
     
    266264{
    267265    static bool cached = false;
    268 
    269 #if GIGACAGE_ENABLED
    270266    static std::once_flag onceFlag;
    271267    std::call_once(
     
    289285            cached = true;
    290286        });
     287    return cached;
     288}
     289
     290} // namespace Gigacage
     291
    291292#endif // GIGACAGE_ENABLED
    292    
    293     return cached;
    294 }
    295 
    296 } // namespace Gigacage
    297 
    298 
    299 
     293
     294
  • trunk/Source/bmalloc/bmalloc/Gigacage.h

    r240171 r240175  
    3131#include "BInline.h"
    3232#include "BPlatform.h"
     33#include "Sizes.h"
    3334#include <cstddef>
    3435#include <inttypes.h>
    3536
    36 #if BCPU(ARM64)
    37 #define PRIMITIVE_GIGACAGE_SIZE 0x80000000llu
    38 #define JSVALUE_GIGACAGE_SIZE 0x40000000llu
    39 #define GIGACAGE_ALLOCATION_CAN_FAIL 1
    40 #else
    41 #define PRIMITIVE_GIGACAGE_SIZE 0x800000000llu
    42 #define JSVALUE_GIGACAGE_SIZE 0x400000000llu
    43 #define GIGACAGE_ALLOCATION_CAN_FAIL 0
    44 #endif
    45 
    46 // In Linux, if `vm.overcommit_memory = 2` is specified, mmap with large size can fail if it exceeds the size of RAM.
    47 // So we specify GIGACAGE_ALLOCATION_CAN_FAIL = 1.
    48 #if BOS(LINUX)
    49 #undef GIGACAGE_ALLOCATION_CAN_FAIL
    50 #define GIGACAGE_ALLOCATION_CAN_FAIL 1
    51 #endif
    52 
    53 static_assert(bmalloc::isPowerOfTwo(PRIMITIVE_GIGACAGE_SIZE), "");
    54 static_assert(bmalloc::isPowerOfTwo(JSVALUE_GIGACAGE_SIZE), "");
    55 
    56 #define GIGACAGE_SIZE_TO_MASK(size) ((size) - 1)
    57 
    58 #define PRIMITIVE_GIGACAGE_MASK GIGACAGE_SIZE_TO_MASK(PRIMITIVE_GIGACAGE_SIZE)
    59 #define JSVALUE_GIGACAGE_MASK GIGACAGE_SIZE_TO_MASK(JSVALUE_GIGACAGE_SIZE)
    60 
    6137#if ((BOS(DARWIN) || BOS(LINUX)) && \
    62     (BCPU(X86_64) || (BCPU(ARM64) && !defined(__ILP32__) && (!BPLATFORM(IOS_FAMILY) || BPLATFORM(IOS)))))
     38(BCPU(X86_64) || (BCPU(ARM64) && !defined(__ILP32__) && (!BPLATFORM(IOS_FAMILY) || BPLATFORM(IOS)))))
    6339#define GIGACAGE_ENABLED 1
    6440#else
     
    6642#endif
    6743
    68 #if BCPU(ARM64)
    69 #define GIGACAGE_BASE_PTRS_SIZE 16384
    70 #else
    71 #define GIGACAGE_BASE_PTRS_SIZE 4096
    72 #endif
    73 
    74 extern "C" alignas(GIGACAGE_BASE_PTRS_SIZE) BEXPORT char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE];
    7544
    7645namespace Gigacage {
    77 
    78 BINLINE bool wasEnabled() { return g_gigacageBasePtrs[0]; }
    79 BINLINE void setWasEnabled() { g_gigacageBasePtrs[0] = true; }
    80 
    81 struct BasePtrs {
    82     uintptr_t reservedForFlags;
    83     void* primitive;
    84     void* jsValue;
    85 };
    8646
    8747enum Kind {
     
    9050    JSValue,
    9151};
    92 
    93 static_assert(offsetof(BasePtrs, primitive) == Kind::Primitive * sizeof(void*), "");
    94 static_assert(offsetof(BasePtrs, jsValue) == Kind::JSValue * sizeof(void*), "");
    95 
    96 static constexpr unsigned numKinds = 2;
    97 
    98 BEXPORT void ensureGigacage();
    99 
    100 BEXPORT void disablePrimitiveGigacage();
    101 
    102 // This will call the disable callback immediately if the Primitive Gigacage is currently disabled.
    103 BEXPORT void addPrimitiveDisableCallback(void (*)(void*), void*);
    104 BEXPORT void removePrimitiveDisableCallback(void (*)(void*), void*);
    105 
    106 BEXPORT void disableDisablingPrimitiveGigacageIfShouldBeEnabled();
    107 
    108 BEXPORT bool isDisablingPrimitiveGigacageDisabled();
    109 inline bool isPrimitiveGigacagePermanentlyEnabled() { return isDisablingPrimitiveGigacageDisabled(); }
    110 inline bool canPrimitiveGigacageBeDisabled() { return !isDisablingPrimitiveGigacageDisabled(); }
    11152
    11253BINLINE const char* name(Kind kind)
     
    12465}
    12566
     67#if GIGACAGE_ENABLED
     68
     69#if BCPU(ARM64)
     70constexpr size_t primitiveGigacageSize = 2 * bmalloc::Sizes::GB;
     71constexpr size_t jsValueGigacageSize = 1 * bmalloc::Sizes::GB;
     72constexpr size_t gigacageBasePtrsSize = 16 * bmalloc::Sizes::kB;
     73constexpr size_t minimumCageSizeAfterSlide = bmalloc::Sizes::GB / 2;
     74#define GIGACAGE_ALLOCATION_CAN_FAIL 1
     75#else
     76constexpr size_t primitiveGigacageSize = 32 * bmalloc::Sizes::GB;
     77constexpr size_t jsValueGigacageSize = 16 * bmalloc::Sizes::GB;
     78constexpr size_t gigacageBasePtrsSize = 4 * bmalloc::Sizes::kB;
     79constexpr size_t minimumCageSizeAfterSlide = 4 * bmalloc::Sizes::GB;
     80#define GIGACAGE_ALLOCATION_CAN_FAIL 0
     81#endif
     82
     83// In Linux, if `vm.overcommit_memory = 2` is specified, mmap with large size can fail if it exceeds the size of RAM.
     84// So we specify GIGACAGE_ALLOCATION_CAN_FAIL = 1.
     85#if BOS(LINUX)
     86#undef GIGACAGE_ALLOCATION_CAN_FAIL
     87#define GIGACAGE_ALLOCATION_CAN_FAIL 1
     88#endif
     89
     90
     91static_assert(bmalloc::isPowerOfTwo(primitiveGigacageSize), "");
     92static_assert(bmalloc::isPowerOfTwo(jsValueGigacageSize), "");
     93static_assert(primitiveGigacageSize > minimumCageSizeAfterSlide, "");
     94static_assert(jsValueGigacageSize > minimumCageSizeAfterSlide, "");
     95
     96constexpr size_t gigacageSizeToMask(size_t size) { return size - 1; }
     97
     98constexpr size_t primitiveGigacageMask = gigacageSizeToMask(primitiveGigacageSize);
     99constexpr size_t jsValueGigacageMask = gigacageSizeToMask(jsValueGigacageSize);
     100
     101extern "C" alignas(gigacageBasePtrsSize) BEXPORT char g_gigacageBasePtrs[gigacageBasePtrsSize];
     102
     103BINLINE bool wasEnabled() { return g_gigacageBasePtrs[0]; }
     104BINLINE void setWasEnabled() { g_gigacageBasePtrs[0] = true; }
     105
     106struct BasePtrs {
     107    uintptr_t reservedForFlags;
     108    void* primitive;
     109    void* jsValue;
     110};
     111
     112static_assert(offsetof(BasePtrs, primitive) == Kind::Primitive * sizeof(void*), "");
     113static_assert(offsetof(BasePtrs, jsValue) == Kind::JSValue * sizeof(void*), "");
     114
     115constexpr unsigned numKinds = 2;
     116
     117BEXPORT void ensureGigacage();
     118
     119BEXPORT void disablePrimitiveGigacage();
     120
     121// This will call the disable callback immediately if the Primitive Gigacage is currently disabled.
     122BEXPORT void addPrimitiveDisableCallback(void (*)(void*), void*);
     123BEXPORT void removePrimitiveDisableCallback(void (*)(void*), void*);
     124
     125BEXPORT void disableDisablingPrimitiveGigacageIfShouldBeEnabled();
     126
     127BEXPORT bool isDisablingPrimitiveGigacageDisabled();
     128inline bool isPrimitiveGigacagePermanentlyEnabled() { return isDisablingPrimitiveGigacageDisabled(); }
     129inline bool canPrimitiveGigacageBeDisabled() { return !isDisablingPrimitiveGigacageDisabled(); }
     130
    126131BINLINE void*& basePtr(BasePtrs& basePtrs, Kind kind)
    127132{
     
    159164        RELEASE_BASSERT_NOT_REACHED();
    160165    case Primitive:
    161         return static_cast<size_t>(PRIMITIVE_GIGACAGE_SIZE);
     166        return static_cast<size_t>(primitiveGigacageSize);
    162167    case JSValue:
    163         return static_cast<size_t>(JSVALUE_GIGACAGE_SIZE);
     168        return static_cast<size_t>(jsValueGigacageSize);
    164169    }
    165170    BCRASH();
     
    174179BINLINE size_t mask(Kind kind)
    175180{
    176     return GIGACAGE_SIZE_TO_MASK(size(kind));
     181    return gigacageSizeToMask(size(kind));
    177182}
    178183
     
    203208BEXPORT bool shouldBeEnabled();
    204209
     210#else // GIGACAGE_ENABLED
     211
     212BINLINE void*& basePtr(Kind)
     213{
     214    BCRASH();
     215    static void* unreachable;
     216    return unreachable;
     217}
     218BINLINE size_t size(Kind) { BCRASH(); return 0; }
     219BINLINE void ensureGigacage() { }
     220BINLINE bool wasEnabled() { return false; }
     221BINLINE bool isCaged(Kind, const void*) { return true; }
     222BINLINE bool isEnabled() { return false; }
     223template<typename T> BINLINE T* caged(Kind, T* ptr) { return ptr; }
     224BINLINE void disableDisablingPrimitiveGigacageIfShouldBeEnabled() { }
     225BINLINE bool canPrimitiveGigacageBeDisabled() { return false; }
     226BINLINE void disablePrimitiveGigacage() { }
     227BINLINE void addPrimitiveDisableCallback(void (*)(void*), void*) { }
     228BINLINE void removePrimitiveDisableCallback(void (*)(void*), void*) { }
     229
     230#endif // GIGACAGE_ENABLED
     231
    205232} // namespace Gigacage
    206233
    207234
     235
  • trunk/Source/bmalloc/bmalloc/Heap.cpp

    r240171 r240175  
    3030#include "BumpAllocator.h"
    3131#include "Chunk.h"
     32#include "CryptoRandom.h"
    3233#include "Environment.h"
    3334#include "Gigacage.h"
     
    6263        if (usingGigacage()) {
    6364            RELEASE_BASSERT(gigacageBasePtr());
    64             m_largeFree.add(LargeRange(gigacageBasePtr(), gigacageSize(), 0, 0));
     65            uint64_t random;
     66            cryptoRandom(reinterpret_cast<unsigned char*>(&random), sizeof(random));
     67            ptrdiff_t offset = random % (gigacageSize() - Gigacage::minimumCageSizeAfterSlide);
     68            offset = reinterpret_cast<ptrdiff_t>(roundDownToMultipleOf(vmPageSize(), reinterpret_cast<void*>(offset)));
     69            void* base = reinterpret_cast<unsigned char*>(gigacageBasePtr()) + offset;
     70            m_largeFree.add(LargeRange(base, gigacageSize() - offset, 0, 0));
    6571        }
    6672#endif
  • trunk/Source/bmalloc/bmalloc/Sizes.h

    r240171 r240175  
    4141
    4242namespace Sizes {
    43     static const size_t kB = 1024;
    44     static const size_t MB = kB * kB;
     43static constexpr size_t kB = 1024;
     44static constexpr size_t MB = kB * kB;
     45static constexpr size_t GB = kB * kB * kB;
    4546
    46     static const size_t alignment = 8;
    47     static const size_t alignmentMask = alignment - 1ul;
     47static constexpr size_t alignment = 8;
     48static constexpr size_t alignmentMask = alignment - 1ul;
    4849
    49     static const size_t chunkSize = 1 * MB;
    50     static const size_t chunkMask = ~(chunkSize - 1ul);
     50static constexpr size_t chunkSize = 1 * MB;
     51static constexpr size_t chunkMask = ~(chunkSize - 1ul);
    5152
    52     static const size_t smallLineSize = 256;
    53     static const size_t smallPageSize = 4 * kB;
    54     static const size_t smallPageLineCount = smallPageSize / smallLineSize;
     53static constexpr size_t smallLineSize = 256;
     54static constexpr size_t smallPageSize = 4 * kB;
     55static constexpr size_t smallPageLineCount = smallPageSize / smallLineSize;
    5556
    56     static const size_t maskSizeClassMax = 512;
    57     static const size_t smallMax = 32 * kB;
     57static constexpr size_t maskSizeClassMax = 512;
     58static constexpr size_t smallMax = 32 * kB;
    5859
    59     static const size_t pageSizeMax = smallMax * 2;
    60     static const size_t pageClassCount = pageSizeMax / smallPageSize;
     60static constexpr size_t pageSizeMax = smallMax * 2;
     61static constexpr size_t pageClassCount = pageSizeMax / smallPageSize;
    6162
    62     static const size_t pageSizeWasteFactor = 8;
    63     static const size_t logWasteFactor = 8;
     63static constexpr size_t pageSizeWasteFactor = 8;
     64static constexpr size_t logWasteFactor = 8;
    6465
    65     static const size_t largeAlignment = smallMax / pageSizeWasteFactor;
    66     static const size_t largeAlignmentMask = largeAlignment - 1;
     66static constexpr size_t largeAlignment = smallMax / pageSizeWasteFactor;
     67static constexpr size_t largeAlignmentMask = largeAlignment - 1;
    6768
    68     static const size_t deallocatorLogCapacity = 512;
    69     static const size_t bumpRangeCacheCapacity = 3;
    70    
    71     static const size_t scavengerBytesPerMemoryPressureCheck = 16 * MB;
    72     static const double memoryPressureThreshold = 0.75;
    73    
    74     static const size_t maskSizeClassCount = maskSizeClassMax / alignment;
     69static constexpr size_t deallocatorLogCapacity = 512;
     70static constexpr size_t bumpRangeCacheCapacity = 3;
    7571
    76     constexpr size_t maskSizeClass(size_t size)
    77     {
    78         // We mask to accommodate zero.
    79         return mask((size - 1) / alignment, maskSizeClassCount - 1);
    80     }
     72static constexpr size_t scavengerBytesPerMemoryPressureCheck = 16 * MB;
     73static constexpr double memoryPressureThreshold = 0.75;
    8174
    82     inline size_t maskObjectSize(size_t maskSizeClass)
    83     {
    84         return (maskSizeClass + 1) * alignment;
    85     }
     75static constexpr size_t maskSizeClassCount = maskSizeClassMax / alignment;
    8676
    87     static const size_t logAlignmentMin = maskSizeClassMax / logWasteFactor;
     77constexpr size_t maskSizeClass(size_t size)
     78{
     79    // We mask to accommodate zero.
     80    return mask((size - 1) / alignment, maskSizeClassCount - 1);
     81}
    8882
    89     static const size_t logSizeClassCount = (log2(smallMax) - log2(maskSizeClassMax)) * logWasteFactor;
     83inline size_t maskObjectSize(size_t maskSizeClass)
     84{
     85    return (maskSizeClass + 1) * alignment;
     86}
    9087
    91     inline size_t logSizeClass(size_t size)
    92     {
    93         size_t base = log2(size - 1) - log2(maskSizeClassMax);
    94         size_t offset = (size - 1 - (maskSizeClassMax << base));
    95         return base * logWasteFactor + offset / (logAlignmentMin << base);
    96     }
     88static constexpr size_t logAlignmentMin = maskSizeClassMax / logWasteFactor;
    9789
    98     inline size_t logObjectSize(size_t logSizeClass)
    99     {
    100         size_t base = logSizeClass / logWasteFactor;
    101         size_t offset = logSizeClass % logWasteFactor;
    102         return (maskSizeClassMax << base) + (offset + 1) * (logAlignmentMin << base);
    103     }
     90static constexpr size_t logSizeClassCount = (log2(smallMax) - log2(maskSizeClassMax)) * logWasteFactor;
    10491
    105     static const size_t sizeClassCount = maskSizeClassCount + logSizeClassCount;
     92inline size_t logSizeClass(size_t size)
     93{
     94    size_t base = log2(size - 1) - log2(maskSizeClassMax);
     95    size_t offset = (size - 1 - (maskSizeClassMax << base));
     96    return base * logWasteFactor + offset / (logAlignmentMin << base);
     97}
    10698
    107     inline size_t sizeClass(size_t size)
    108     {
    109         if (size <= maskSizeClassMax)
    110             return maskSizeClass(size);
    111         return maskSizeClassCount + logSizeClass(size);
    112     }
     99inline size_t logObjectSize(size_t logSizeClass)
     100{
     101    size_t base = logSizeClass / logWasteFactor;
     102    size_t offset = logSizeClass % logWasteFactor;
     103    return (maskSizeClassMax << base) + (offset + 1) * (logAlignmentMin << base);
     104}
    113105
    114     inline size_t objectSize(size_t sizeClass)
    115     {
    116         if (sizeClass < maskSizeClassCount)
    117             return maskObjectSize(sizeClass);
    118         return logObjectSize(sizeClass - maskSizeClassCount);
    119     }
    120    
    121     inline size_t pageSize(size_t pageClass)
    122     {
    123         return (pageClass + 1) * smallPageSize;
    124     }
     106static constexpr size_t sizeClassCount = maskSizeClassCount + logSizeClassCount;
     107
     108inline size_t sizeClass(size_t size)
     109{
     110    if (size <= maskSizeClassMax)
     111        return maskSizeClass(size);
     112    return maskSizeClassCount + logSizeClass(size);
    125113}
     114
     115inline size_t objectSize(size_t sizeClass)
     116{
     117    if (sizeClass < maskSizeClassCount)
     118        return maskObjectSize(sizeClass);
     119    return logObjectSize(sizeClass - maskSizeClassCount);
     120}
     121
     122inline size_t pageSize(size_t pageClass)
     123{
     124    return (pageClass + 1) * smallPageSize;
     125}
     126} // namespace Sizes
    126127
    127128using namespace Sizes;
Note: See TracChangeset for help on using the changeset viewer.