Changeset 293710 in webkit
- Timestamp:
- May 2, 2022, 8:02:04 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 15 edited
-
ChangeLog (modified) (1 diff)
-
ftl/FTLLowerDFGToB3.cpp (modified) (1 diff)
-
heap/Heap.cpp (modified) (1 diff)
-
heap/IsoSubspace.h (modified) (1 diff)
-
heap/IsoSubspaceInlines.h (modified) (1 diff)
-
heap/StructureAlignedMemoryAllocator.cpp (modified) (2 diffs)
-
jit/AssemblyHelpers.cpp (modified) (1 diff)
-
llint/LLIntOfflineAsmConfig.h (modified) (2 diffs)
-
llint/LowLevelInterpreter64.asm (modified) (1 diff)
-
runtime/JSCell.h (modified) (1 diff)
-
runtime/JSCellInlines.h (modified) (1 diff)
-
runtime/Structure.cpp (modified) (3 diffs)
-
runtime/Structure.h (modified) (1 diff)
-
runtime/StructureID.h (modified) (2 diffs)
-
tools/IntegrityInlines.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r293708 r293710 1 2022-05-02 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Introduce shifting Structure encoding 4 https://bugs.webkit.org/show_bug.cgi?id=239957 5 6 Reviewed by Mark Lam. 7 8 For platforms which have limited amount of virtual address space (<= 36 bits), this patch introduces 9 shifting Structure encoding. We align Structure on a 32-bytes boundary instead of 16 bytes so that 10 we can ensure that lower 5 bits are zero. Then, we can use 1 bit for nuke, and shifting 4 bits to 11 convert 36 bit address to 32 bit StructureID. By using this mechanism, we do not need to allocate 12 large virtual address space for these platforms. If we an address can have more than 36 bits, then 13 we should just reserve a larger address region since we have enough address space. Current Structure 14 size is 112 bytes, which is 3.5 atoms at 32 bytes / atom. Hence, this alignment costs us 16 bytes per 15 Structure. 16 Relanding with debug build failure & crash on static atomSize assumption in IsoSubspace. 17 18 * ftl/FTLLowerDFGToB3.cpp: 19 (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): 20 * heap/Heap.cpp: 21 * heap/IsoSubspace.h: 22 (JSC::GCClient::IsoSubspace::allocatorFor): 23 * heap/IsoSubspaceInlines.h: 24 (JSC::GCClient::IsoSubspace::allocate): 25 * heap/StructureAlignedMemoryAllocator.cpp: 26 (JSC::StructureMemoryManager::StructureMemoryManager): 27 * jit/AssemblyHelpers.cpp: 28 (JSC::AssemblyHelpers::emitNonNullDecodeStructureID): 29 * llint/LLIntOfflineAsmConfig.h: 30 * llint/LowLevelInterpreter64.asm: 31 * runtime/JSCell.h: 32 * runtime/JSCellInlines.h: 33 (JSC::JSCell::JSCell): 34 * runtime/Structure.cpp: 35 (JSC::Structure::Structure): 36 * runtime/Structure.h: 37 * runtime/StructureID.h: 38 (JSC::StructureID::decode const): 39 (JSC::StructureID::tryDecode const): 40 (JSC::StructureID::encode): 41 * tools/IntegrityInlines.h: 42 (JSC::Integrity::auditStructureID): 43 1 44 2022-05-01 Yusuke Suzuki <ysuzuki@apple.com> 2 45 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r293685 r293710 21015 21015 LValue decodeNonNullStructure(LValue structureID) 21016 21016 { 21017 LValue maskedStructureID = m_out.bitAnd(structureID, m_out.constInt32(structureIDMask)); 21017 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 21018 return m_out.shl(m_out.zeroExtPtr(structureID), m_out.constIntPtr(StructureID::encodeShiftAmount)); 21019 #else 21020 LValue maskedStructureID = m_out.bitAnd(structureID, m_out.constInt32(StructureID::structureIDMask)); 21018 21021 return m_out.add(m_out.constIntPtr(g_jscConfig.startOfStructureHeap), m_out.zeroExtPtr(maskedStructureID)); 21022 #endif 21019 21023 } 21020 21024 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r293685 r293710 270 270 271 271 #define INIT_SERVER_STRUCTURE_ISO_SUBSPACE(name, heapCellType, type) \ 272 , name("Isolated" #name "Space", *this, heapCellType, sizeof(type), type::numberOfLowerTierCells, makeUnique<StructureAlignedMemoryAllocator>("Structure"))272 , name("Isolated" #name "Space", *this, heapCellType, WTF::roundUpToMultipleOf<type::atomSize>(sizeof(type)), type::numberOfLowerTierCells, makeUnique<StructureAlignedMemoryAllocator>("Structure")) 273 273 274 274 Heap::Heap(VM& vm, HeapType heapType) -
trunk/Source/JavaScriptCore/heap/IsoSubspace.h
r290129 r293710 93 93 ALWAYS_INLINE Allocator IsoSubspace::allocatorFor(size_t size, AllocatorForMode) 94 94 { 95 RELEASE_ASSERT( WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size) == cellSize());95 RELEASE_ASSERT(size <= cellSize()); 96 96 return Allocator(&m_localAllocator); 97 97 } -
trunk/Source/JavaScriptCore/heap/IsoSubspaceInlines.h
r290129 r293710 32 32 ALWAYS_INLINE void* IsoSubspace::allocate(VM& vm, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode) 33 33 { 34 RELEASE_ASSERT( WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(size) == cellSize());34 RELEASE_ASSERT(size <= cellSize()); 35 35 Allocator allocator = allocatorFor(size, AllocatorForMode::MustAlreadyHaveAllocator); 36 36 void* result = allocator.allocate(vm.heap, deferralContext, failureMode); -
trunk/Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp
r293685 r293710 67 67 } 68 68 69 #if CPU(ADDRESS64) 69 #if CPU(ADDRESS64) && !ENABLE(STRUCTURE_ID_WITH_SHIFT) 70 70 71 71 class StructureMemoryManager { … … 84 84 } 85 85 g_jscConfig.sizeOfStructureHeap = mappedHeapSize; 86 RELEASE_ASSERT(g_jscConfig.startOfStructureHeap && ((g_jscConfig.startOfStructureHeap & ~ structureIDMask) == g_jscConfig.startOfStructureHeap));86 RELEASE_ASSERT(g_jscConfig.startOfStructureHeap && ((g_jscConfig.startOfStructureHeap & ~StructureID::structureIDMask) == g_jscConfig.startOfStructureHeap)); 87 87 } 88 88 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r293685 r293710 406 406 void AssemblyHelpers::emitNonNullDecodeStructureID(RegisterID source, RegisterID dest) 407 407 { 408 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 409 lshift64(source, TrustedImm32(StructureID::encodeShiftAmount), dest); 410 #elif CPU(ADDRESS64) 411 // This could use BFI on arm64 but that only helps if the start of structure heap is encodable as a mov and not as an immediate in the add so it's probably not super important. 412 and32(TrustedImm32(StructureID::structureIDMask), source, dest); 413 add64(TrustedImm64(g_jscConfig.startOfStructureHeap), dest); 414 #else // not CPU(ADDRESS64) 408 415 move(source, dest); 409 #if CPU(ADDRESS64) 410 // This could use BFI on arm64 but that only helps if the start of structure heap is encodable as a mov and not as an immediate in the add so it's probably not super important. 411 and32(TrustedImm32(structureIDMask), dest); 412 add64(TrustedImm64(g_jscConfig.startOfStructureHeap), dest); 413 #endif // not CPU(ADDRESS64) 416 #endif 414 417 } 415 418 -
trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
r293685 r293710 27 27 28 28 #include "LLIntCommon.h" 29 #include "StructureID.h" 29 30 #include <wtf/Assertions.h> 30 31 #include <wtf/Gigacage.h> … … 162 163 #endif 163 164 165 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 166 #define OFFLINE_ASM_STRUCTURE_ID_WITH_SHIFT 1 167 #else 168 #define OFFLINE_ASM_STRUCTURE_ID_WITH_SHIFT 0 169 #endif 170 164 171 #if ASSERT_ENABLED 165 172 #define OFFLINE_ASM_ASSERT_ENABLED 1 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r293685 r293710 742 742 743 743 macro structureIDToStructureWithScratch(structureIDThenStructure, scratch) 744 if ADDRESS64 745 andq constexpr structureIDMask, structureIDThenStructure 744 if STRUCTURE_ID_WITH_SHIFT 745 lshiftp (constexpr StructureID::encodeShiftAmount), structureIDThenStructure 746 elsif ADDRESS64 747 andq (constexpr StructureID::structureIDMask), structureIDThenStructure 746 748 leap JSCConfig + constexpr JSC::offsetOfJSCConfigStartOfStructureHeap, scratch 747 749 loadp [scratch], scratch -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r293685 r293710 90 90 static constexpr uint8_t numberOfLowerTierCells = 8; 91 91 92 static constexpr size_t atomSize = 16; // This needs to be larger or equal to 16. 93 92 94 static JSCell* seenMultipleCalleeObjects() { return bitwise_cast<JSCell*>(static_cast<uintptr_t>(1)); } 93 95 -
trunk/Source/JavaScriptCore/runtime/JSCellInlines.h
r293685 r293710 76 76 // structure pointer is still alive at this point. 77 77 ensureStillAliveHere(structure); 78 static_assert(JSCell::atomSize >= MarkedBlock::atomSize); 78 79 } 79 80 -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r293685 r293710 233 233 234 234 validateFlags(); 235 236 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 237 ASSERT(WTF::roundUpToMultipleOf<Structure::atomSize>(this) == this); 238 #endif 235 239 } 236 240 … … 271 275 ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 272 276 ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData); 277 278 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 279 ASSERT(WTF::roundUpToMultipleOf<Structure::atomSize>(this) == this); 280 #endif 273 281 } 274 282 … … 320 328 ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties()); 321 329 ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData); 330 331 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 332 ASSERT(WTF::roundUpToMultipleOf<Structure::atomSize>(this) == this); 333 #endif 322 334 } 323 335 -
trunk/Source/JavaScriptCore/runtime/Structure.h
r293685 r293710 175 175 static constexpr unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 176 176 static constexpr uint8_t numberOfLowerTierCells = 0; 177 177 178 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 179 static constexpr size_t atomSize = 32; 180 #endif 181 static_assert(JSCell::atomSize >= MarkedBlock::atomSize); 182 178 183 enum PolyProtoTag { PolyProto }; 179 184 static Structure* create(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0); -
trunk/Source/JavaScriptCore/runtime/StructureID.h
r293685 r293710 35 35 class Structure; 36 36 37 constexpr CPURegister structureIDMask = structureHeapAddressSize - 1; 37 // We would like to define this value in PlatformEnable.h, but it is not possible since the following is relying on MACH_VM_MAX_ADDRESS. 38 #if CPU(ADDRESS64) && CPU(ARM64) && OS(DARWIN) 39 #if MACH_VM_MAX_ADDRESS_RAW < (1ULL << 36) 40 #define ENABLE_STRUCTURE_ID_WITH_SHIFT 1 41 static_assert(MACH_VM_MAX_ADDRESS_RAW == MACH_VM_MAX_ADDRESS); 42 #endif 43 #endif 38 44 39 45 class StructureID { 40 46 public: 41 47 static constexpr uint32_t nukedStructureIDBit = 1; 48 49 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 50 // ENABLE(STRUCTURE_ID_WITH_SHIFT) is used when our virtual memory space is limited (specifically, less than or equal to 36 bit) while pointer is 64 bit. 51 // In that case, we round up Structures size with 32 bytes instead of 16 bytes. This ensures that lower 5 bit become zero for Structure. 52 // By shifting this address with 4, we can encode 36 bit address into 32 bit StructureID. And we can ensure that StructureID's lowest bit is still zero 53 // because we round Structure size with 32 bytes. This lowest bit is used for nuke bit. 54 static constexpr unsigned encodeShiftAmount = 4; 55 #elif CPU(ADDRESS64) 56 static constexpr CPURegister structureIDMask = structureHeapAddressSize - 1; 57 #endif 42 58 43 59 StructureID() = default; … … 68 84 static_assert(sizeof(StructureID) == sizeof(uint32_t)); 69 85 70 #if CPU(ADDRESS64) 86 #if ENABLE(STRUCTURE_ID_WITH_SHIFT) 87 88 ALWAYS_INLINE Structure* StructureID::decode() const 89 { 90 ASSERT(decontaminate()); 91 return reinterpret_cast<Structure*>(static_cast<uintptr_t>(m_bits) << encodeShiftAmount); 92 } 93 94 ALWAYS_INLINE Structure* StructureID::tryDecode() const 95 { 96 // Take care to only use the bits from m_bits in the structure's address reservation. 97 uintptr_t address = static_cast<uintptr_t>(decontaminate().m_bits) << encodeShiftAmount; 98 if (address < MarkedBlock::blockSize) 99 return nullptr; 100 return reinterpret_cast<Structure*>(address); 101 } 102 103 ALWAYS_INLINE StructureID StructureID::encode(const Structure* structure) 104 { 105 ASSERT(structure); 106 auto result = StructureID(reinterpret_cast<uintptr_t>(structure) >> encodeShiftAmount); 107 ASSERT(result.decode() == structure); 108 return result; 109 } 110 111 #elif CPU(ADDRESS64) 71 112 72 113 ALWAYS_INLINE Structure* StructureID::decode() const -
trunk/Source/JavaScriptCore/tools/IntegrityInlines.h
r293685 r293710 78 78 { 79 79 UNUSED_PARAM(structureID); 80 #if CPU(ADDRESS64) 80 #if CPU(ADDRESS64) && !ENABLE(STRUCTURE_ID_WITH_SHIFT) 81 81 ASSERT(structureID.bits() <= structureHeapAddressSize + StructureID::nukedStructureIDBit); 82 82 #endif
Note:
See TracChangeset
for help on using the changeset viewer.