Skip to content

Commit

Permalink
Shrink Structure to 96 Bytes when addresses can be encoded in 36-bits
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=240407

Reviewed by Yusuke Suzuki.

We have 2% RAMification regression on iOS, which needs a memory performance
improvement. To work towards resolving this regression, this patch is to
reduce JS object's structure size from 112 bytes to 96 bytes for iOS systems.

1. We can reduce 36-bit addresses into 4 bytes when dealing with pointers that
have 16-byte alignment.
2. StructureID can be removed from StructureIDBlob since we can directly compute
the id by encoding the Structure pointer.

CompactPtr and CompactRefPtr classes are introduced for pointers, which can
achieve 8 bytes in MacOS and 4 bytes in iOS.

* PerformanceTests/JetStream2/RexBench/OfflineAssembler/LowLevelInterpreter64.asm:
* PerformanceTests/JetStream2/RexBench/OfflineAssembler/LowLevelInterpreter64.js:
* PerformanceTests/JetStream2/RexBench/OfflineAssembler/expected.js:
* PerformanceTests/RexBench/OfflineAssembler/LowLevelInterpreter64.asm:
* PerformanceTests/RexBench/OfflineAssembler/LowLevelInterpreter64.js:
* PerformanceTests/RexBench/OfflineAssembler/expected.js:
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/bytecode/GetByValHistory.h:
(JSC::GetByValHistory::observe):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp:
(JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
* Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/heap/ConservativeRoots.cpp:
(JSC::ConservativeRoots::genericAddPointer):
(JSC::ConservativeRoots::genericAddSpan):
* Source/JavaScriptCore/heap/ConservativeRoots.h:
* Source/JavaScriptCore/heap/HeapSnapshot.h:
* Source/JavaScriptCore/heap/HeapUtil.h:
(JSC::HeapUtil::findGCObjectPointersForMarking):
(JSC::HeapUtil::isPointerGCObjectJSCell):
(JSC::HeapUtil::isValueGCObject):
* Source/JavaScriptCore/heap/MarkedBlockSet.h:
(JSC::MarkedBlockSet::add):
(JSC::MarkedBlockSet::recomputeFilter):
(JSC::MarkedBlockSet::filter const):
* Source/JavaScriptCore/heap/TinyBloomFilter.h:
(JSC::TinyBloomFilter<Bits>::TinyBloomFilter):
(JSC::TinyBloomFilter<Bits>::add):
(JSC::TinyBloomFilter<Bits>::ruleOut const):
(JSC::TinyBloomFilter<Bits>::reset):
(JSC::TinyBloomFilter::TinyBloomFilter): Deleted.
(JSC::TinyBloomFilter::add): Deleted.
(JSC::TinyBloomFilter::ruleOut const): Deleted.
(JSC::TinyBloomFilter::reset): Deleted.
* Source/JavaScriptCore/jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo):
(JSC::AssemblyHelpers::emitEncodeStructure):
* Source/JavaScriptCore/jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitStoreStructureWithTypeInfo):
(JSC::AssemblyHelpers::loadCompactPtr):
(JSC::AssemblyHelpers::branchCompactPtr):
* Source/JavaScriptCore/jit/JITPropertyAccess.cpp:
(JSC::JIT::generateOpGetFromScopeThunk):
(JSC::JIT::emit_op_put_to_scope):
* Source/JavaScriptCore/runtime/ClassInfo.h:
(JSC::ClassInfo::offsetOfParentClass): Deleted.
(JSC::ClassInfo::isSubClassOf const): Deleted.
* Source/JavaScriptCore/runtime/SamplingProfiler.cpp:
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* Source/JavaScriptCore/runtime/Structure.cpp:
(JSC::Structure::Structure):
* Source/JavaScriptCore/runtime/Structure.h:
(JSC::Structure::id const):
(JSC::Structure::typeInfoBlob const):
(JSC::Structure::classInfoForCells const):
(JSC::Structure::indexingModeIncludingHistoryOffset):
(JSC::Structure::objectInitializationBlob const): Deleted.
(JSC::Structure::idBlob const): Deleted.
(JSC::Structure::structureIDOffset): Deleted.
* Source/JavaScriptCore/runtime/StructureInlines.h:
(JSC::Structure::get):
(JSC::Structure::add):
* Source/JavaScriptCore/runtime/TypeInfoBlob.h: Renamed from Source/JavaScriptCore/runtime/StructureIDBlob.h.
(JSC::TypeInfoBlob::TypeInfoBlob):
(JSC::TypeInfoBlob::operator=):
(JSC::TypeInfoBlob::indexingModeIncludingHistory const):
(JSC::TypeInfoBlob::fencedIndexingModeIncludingHistory):
(JSC::TypeInfoBlob::setIndexingModeIncludingHistory):
(JSC::TypeInfoBlob::type const):
(JSC::TypeInfoBlob::inlineTypeFlags const):
(JSC::TypeInfoBlob::typeInfo const):
(JSC::TypeInfoBlob::blob const):
(JSC::TypeInfoBlob::indexingModeIncludingHistoryOffset):
* Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::jsCallEntrypointSlow):
* Source/WTF/WTF.xcodeproj/project.pbxproj:
* Source/WTF/wtf/CMakeLists.txt:
* Source/WTF/wtf/CompactPtr.h: Added.
(WTF::CompactPtr::CompactPtr):
(WTF::CompactPtr::operator* const):
(WTF::CompactPtr::operator-> const):
(WTF::CompactPtr::operator! const):
(WTF::CompactPtr::operator bool const):
(WTF::CompactPtr::operator=):
(WTF::CompactPtr::get const):
(WTF::CompactPtr::set):
(WTF::CompactPtr::exchange):
(WTF::CompactPtr::swap):
(WTF::CompactPtr::encode):
(WTF::CompactPtr::encode const):
(WTF::CompactPtr::decode const):
(WTF::GetPtrHelper<CompactPtr<T>>::getPtr):
(WTF::CompactPtrTraits::exchange):
(WTF::CompactPtrTraits::swap):
(WTF::CompactPtrTraits::unwrap):
(WTF::CompactPtrTraits::hashTableDeletedValue):
(WTF::CompactPtrTraits::isHashTableDeletedValue):
* Source/WTF/wtf/CompactRefPtr.h: Copied from Source/JavaScriptCore/heap/HeapSnapshot.h.
* Source/WTF/wtf/text/StringImpl.cpp:
* Source/WTF/wtf/text/StringImpl.h:
* Tools/TestWebKitAPI/CMakeLists.txt:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WTF/AlignedRefLogger.h: Copied from Source/JavaScriptCore/heap/TinyBloomFilter.h.
(TestWebKitAPI::DerivedAlignedRefLogger::DerivedAlignedRefLogger):
* Tools/TestWebKitAPI/Tests/WTF/CompactPtr.cpp: Added.
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/Tests/WTF/CompactRefPtr.cpp: Added.
(TestWebKitAPI::TEST):
(TestWebKitAPI::f1):
(TestWebKitAPI::returnConstRefCountedRef):
(TestWebKitAPI::returnRefCountedRef):
(TestWebKitAPI::CompactRefPtrCheckingAlignedRefLogger::CompactRefPtrCheckingAlignedRefLogger):
(TestWebKitAPI::loggerName):
(TestWebKitAPI::CompactRefPtrCheckingAlignedRefLogger::ref):
(TestWebKitAPI::CompactRefPtrCheckingAlignedRefLogger::deref):
* Tools/TestWebKitAPI/Tests/WTF/JSONValue.cpp:
(TestWebKitAPI::TEST):
* Websites/browserbench.org/JetStream2.0/RexBench/OfflineAssembler/LowLevelInterpreter64.asm:
* Websites/browserbench.org/JetStream2.0/RexBench/OfflineAssembler/LowLevelInterpreter64.js:
* Websites/browserbench.org/JetStream2.0/RexBench/OfflineAssembler/expected.js:

Canonical link: https://commits.webkit.org/251103@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295008 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Yijia Huang committed May 29, 2022
1 parent 19a6ec1 commit 771382d
Show file tree
Hide file tree
Showing 35 changed files with 1,290 additions and 107 deletions.
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/CMakeLists.txt
Expand Up @@ -1176,7 +1176,6 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
runtime/StructureCache.h
runtime/StructureChain.h
runtime/StructureID.h
runtime/StructureIDBlob.h
runtime/StructureInlines.h
runtime/StructureRareData.h
runtime/StructureRareDataInlines.h
Expand All @@ -1193,6 +1192,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
runtime/ThrowScope.h
runtime/ToNativeFromValue.h
runtime/TypeError.h
runtime/TypeInfoBlob.h
runtime/TypeSet.h
runtime/TypedArrayAdaptersForwardDeclarations.h
runtime/TypedArrayAdaptors.h
Expand Down
Expand Up @@ -838,7 +838,7 @@
2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */; };
2A83638618D7D0EE0000EBCC /* EdenGCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A83638418D7D0EE0000EBCC /* EdenGCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
2A83638A18D7D0FE0000EBCC /* FullGCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A83638818D7D0FE0000EBCC /* FullGCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */; settings = {ATTRIBUTES = (Private, ); }; };
2AAAA31218BD49D100394CC8 /* TypeInfoBlob.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AAAA31018BD49D100394CC8 /* TypeInfoBlob.h */; settings = {ATTRIBUTES = (Private, ); }; };
2AABCDE718EF294200002096 /* GCLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AABCDE618EF294200002096 /* GCLogging.h */; settings = {ATTRIBUTES = (Private, ); }; };
2AACE63D18CA5A0300ED0191 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AACE63B18CA5A0300ED0191 /* GCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
Expand Down Expand Up @@ -3743,7 +3743,7 @@
2A83638418D7D0EE0000EBCC /* EdenGCActivityCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdenGCActivityCallback.h; sourceTree = "<group>"; };
2A83638718D7D0FE0000EBCC /* FullGCActivityCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FullGCActivityCallback.cpp; sourceTree = "<group>"; };
2A83638818D7D0FE0000EBCC /* FullGCActivityCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullGCActivityCallback.h; sourceTree = "<group>"; };
2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureIDBlob.h; sourceTree = "<group>"; };
2AAAA31018BD49D100394CC8 /* TypeInfoBlob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeInfoBlob.h; sourceTree = "<group>"; };
2AABCDE618EF294200002096 /* GCLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCLogging.h; sourceTree = "<group>"; };
2AACE63A18CA5A0300ED0191 /* GCActivityCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCActivityCallback.cpp; sourceTree = "<group>"; };
2AACE63B18CA5A0300ED0191 /* GCActivityCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCActivityCallback.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -8260,7 +8260,7 @@
7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
7E4EE7080EBB7963005934AA /* StructureChain.h */,
537FEEC82742BDA300C9EFEE /* StructureID.h */,
2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */,
2AAAA31018BD49D100394CC8 /* TypeInfoBlob.h */,
0FD2C92316D01EE900C7803F /* StructureInlines.h */,
C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */,
C2FE18A316BAEC4000AF3061 /* StructureRareData.h */,
Expand Down Expand Up @@ -11100,7 +11100,7 @@
7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */,
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
537FEEC92742BDA300C9EFEE /* StructureID.h in Headers */,
2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */,
2AAAA31218BD49D100394CC8 /* TypeInfoBlob.h in Headers */,
0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/bytecode/GetByValHistory.h
Expand Up @@ -47,7 +47,7 @@ struct GetByValHistory {
uintptr_t count = this->count();
uintptr_t filter = this->filter();

TinyBloomFilter bloomFilter(filter);
TinyBloomFilter<uintptr_t> bloomFilter(filter);
uintptr_t implBits = bitwise_cast<uintptr_t>(impl);
ASSERT(((static_cast<uint64_t>(implBits) << 8) >> 8) == static_cast<uint64_t>(implBits));
if (bloomFilter.ruleOut(implBits)) {
Expand Down
8 changes: 4 additions & 4 deletions Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Expand Up @@ -11106,7 +11106,7 @@ void SpeculativeJIT::compileCheckJSCast(Node* node)
GPRReg specifiedGPR = specified.gpr();

m_jit.emitLoadStructure(vm(), baseGPR, otherGPR);
m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR);
m_jit.loadCompactPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR);
m_jit.move(TrustedImmPtr(node->classInfo()), specifiedGPR);

CCallHelpers::Label loop = m_jit.label();
Expand Down Expand Up @@ -11317,7 +11317,7 @@ void SpeculativeJIT::compileFunctionToString(Node* node)
speculateFunction(node->child1(), function.gpr());

m_jit.emitLoadStructure(vm(), function.gpr(), result.gpr());
m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::classInfoOffset()), result.gpr());
m_jit.loadCompactPtr(JITCompiler::Address(result.gpr(), Structure::classInfoOffset()), result.gpr());
static_assert(std::is_final_v<JSBoundFunction>, "We don't handle subclasses when comparing classInfo below");
slowCases.append(m_jit.branchPtr(CCallHelpers::Equal, result.gpr(), TrustedImmPtr(JSBoundFunction::info())));

Expand Down Expand Up @@ -14886,7 +14886,7 @@ void SpeculativeJIT::compileCreatePromise(Node* node)
slowCases.append(m_jit.branchTest32(CCallHelpers::Zero, structureGPR));
m_jit.emitNonNullDecodeZeroExtendedStructureID(structureGPR, structureGPR);
m_jit.move(TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info()), scratch1GPR);
slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset())));
slowCases.append(m_jit.branchCompactPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset()), scratch2GPR));
m_jit.loadLinkableConstant(JITCompiler::LinkableConstant(m_jit, globalObject), scratch1GPR);
slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset())));

Expand Down Expand Up @@ -14935,7 +14935,7 @@ void SpeculativeJIT::compileCreateInternalFieldObject(Node* node, Operation oper
slowCases.append(m_jit.branchTest32(CCallHelpers::Zero, structureGPR));
m_jit.emitNonNullDecodeZeroExtendedStructureID(structureGPR, structureGPR);
m_jit.move(TrustedImmPtr(JSClass::info()), scratch1GPR);
slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset())));
slowCases.append(m_jit.branchCompactPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset()), scratch2GPR));
m_jit.loadLinkableConstant(JITCompiler::LinkableConstant(m_jit, globalObject), scratch1GPR);
slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset())));

Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp
Expand Up @@ -76,7 +76,7 @@ AbstractHeapRepository::AbstractHeapRepository()
JSCell_header.changeParent(&JSCellHeaderAndNamedProperties);
properties.atAnyNumber().changeParent(&JSCellHeaderAndNamedProperties);

// Make sure that our explicit assumptions about the StructureIDBlob match reality.
// Make sure that our explicit assumptions about the TypeInfoBlob match reality.
RELEASE_ASSERT(!(JSCell_indexingTypeAndMisc.offset() & (sizeof(int32_t) - 1)));
RELEASE_ASSERT(JSCell_indexingTypeAndMisc.offset() + 1 == JSCell_typeInfoType.offset());
RELEASE_ASSERT(JSCell_indexingTypeAndMisc.offset() + 2 == JSCell_typeInfoFlags.offset());
Expand Down
1 change: 0 additions & 1 deletion Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
Expand Up @@ -147,7 +147,6 @@ namespace JSC { namespace FTL {
macro(Structure_outOfLineTypeFlags, Structure::outOfLineTypeFlagsOffset()) \
macro(Structure_previousOrRareData, Structure::previousOrRareDataOffset()) \
macro(Structure_prototype, Structure::prototypeOffset()) \
macro(Structure_structureID, Structure::structureIDOffset()) \
macro(StructureRareData_cachedKeys, StructureRareData::offsetOfCachedPropertyNames(CachedPropertyNamesKind::Keys)) \
macro(StructureRareData_cachedGetOwnPropertyNames, StructureRareData::offsetOfCachedPropertyNames(CachedPropertyNamesKind::GetOwnPropertyNames)) \
macro(StructureRareData_cachedPropertyNameEnumeratorAndFlag, StructureRareData::offsetOfCachedPropertyNameEnumeratorAndFlag()) \
Expand Down
15 changes: 13 additions & 2 deletions Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Expand Up @@ -16839,18 +16839,29 @@ IGNORE_CLANG_WARNINGS_END
{
m_out.store32(m_out.constInt32(structure->id().bits()), object, m_heaps.JSCell_structureID);
m_out.store32(
m_out.constInt32(structure->objectInitializationBlob()),
m_out.constInt32(structure->typeInfoBlob()),
object, m_heaps.JSCell_usefulBytes);
}

LValue encodeStructureID(LValue structure)
{
#if ENABLE(STRUCTURE_ID_WITH_SHIFT)
return m_out.castToInt32(m_out.lShr(structure, m_out.constInt32(StructureID::encodeShiftAmount)));
#elif CPU(ADDRESS64)
return m_out.castToInt32(m_out.bitAnd(structure, m_out.constInt64(StructureID::structureIDMask)));
#else
return m_out.castToInt32(structure);
#endif
}

void storeStructure(LValue object, LValue structure)
{
if (structure->hasIntPtr()) {
storeStructure(object, bitwise_cast<Structure*>(structure->asIntPtr()));
return;
}

LValue id = m_out.load32(structure, m_heaps.Structure_structureID);
LValue id = encodeStructureID(structure);
m_out.store32(id, object, m_heaps.JSCell_structureID);

LValue blob = m_out.load32(structure, m_heaps.Structure_indexingModeIncludingHistory);
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/heap/ConservativeRoots.cpp
Expand Up @@ -63,7 +63,7 @@ void ConservativeRoots::grow()
}

template<typename MarkHook>
inline void ConservativeRoots::genericAddPointer(void* p, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter filter, MarkHook& markHook)
inline void ConservativeRoots::genericAddPointer(void* p, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter<uintptr_t> filter, MarkHook& markHook)
{
p = removeArrayPtrTag(p);
markHook.mark(p);
Expand Down Expand Up @@ -94,7 +94,7 @@ void ConservativeRoots::genericAddSpan(void* begin, void* end, MarkHook& markHoo
RELEASE_ASSERT(isPointerAligned(begin));
RELEASE_ASSERT(isPointerAligned(end));

TinyBloomFilter filter = m_heap.objectSpace().blocks().filter(); // Make a local copy of filter to show the compiler it won't alias, and can be register-allocated.
TinyBloomFilter<uintptr_t> filter = m_heap.objectSpace().blocks().filter(); // Make a local copy of filter to show the compiler it won't alias, and can be register-allocated.
HeapVersion markingVersion = m_heap.objectSpace().markingVersion();
HeapVersion newlyAllocatedVersion = m_heap.objectSpace().newlyAllocatedVersion();
for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it)
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/heap/ConservativeRoots.h
Expand Up @@ -48,7 +48,7 @@ class ConservativeRoots {
static constexpr size_t inlineCapacity = 2048;

template<typename MarkHook>
void genericAddPointer(void*, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter, MarkHook&);
void genericAddPointer(void*, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter<uintptr_t>, MarkHook&);

template<typename MarkHook>
void genericAddSpan(void*, void* end, MarkHook&);
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/heap/HeapSnapshot.h
Expand Up @@ -52,7 +52,7 @@ class HeapSnapshot {
static constexpr intptr_t CellToSweepTag = 1;

Vector<HeapSnapshotNode> m_nodes;
TinyBloomFilter m_filter;
TinyBloomFilter<uintptr_t> m_filter;
HeapSnapshot* m_previous { nullptr };
unsigned m_firstObjectIdentifier { 0 };
unsigned m_lastObjectIdentifier { 0 };
Expand Down
12 changes: 6 additions & 6 deletions Source/JavaScriptCore/heap/HeapUtil.h
Expand Up @@ -46,7 +46,7 @@ class HeapUtil {
// before liveness data is cleared to be accurate.
template<typename Func>
static void findGCObjectPointersForMarking(
Heap& heap, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter filter,
Heap& heap, HeapVersion markingVersion, HeapVersion newlyAllocatedVersion, TinyBloomFilter<uintptr_t> filter,
void* passedPointer, const Func& func)
{
const HashSet<MarkedBlock*>& set = heap.objectSpace().blocks().set();
Expand Down Expand Up @@ -86,7 +86,7 @@ class HeapUtil {
// We may be interested in the last cell of the previous MarkedBlock.
char* previousPointer = bitwise_cast<char*>(bitwise_cast<uintptr_t>(pointer) - sizeof(IndexingHeader) - 1);
MarkedBlock* previousCandidate = MarkedBlock::blockFor(previousPointer);
if (!filter.ruleOut(bitwise_cast<Bits>(previousCandidate))
if (!filter.ruleOut(bitwise_cast<uintptr_t>(previousCandidate))
&& set.contains(previousCandidate)
&& mayHaveIndexingHeader(previousCandidate->handle().cellKind())) {
previousPointer = static_cast<char*>(previousCandidate->handle().cellAlign(previousPointer));
Expand All @@ -95,7 +95,7 @@ class HeapUtil {
}
}

if (filter.ruleOut(bitwise_cast<Bits>(candidate))) {
if (filter.ruleOut(bitwise_cast<uintptr_t>(candidate))) {
ASSERT(!candidate || !set.contains(candidate));
return;
}
Expand Down Expand Up @@ -134,7 +134,7 @@ class HeapUtil {
tryPointer(alignedPointer - candidate->cellSize());
}

static bool isPointerGCObjectJSCell(Heap& heap, TinyBloomFilter filter, JSCell* pointer)
static bool isPointerGCObjectJSCell(Heap& heap, TinyBloomFilter<uintptr_t> filter, JSCell* pointer)
{
// It could point to a large allocation.
if (pointer->isPreciseAllocation()) {
Expand All @@ -148,7 +148,7 @@ class HeapUtil {
const HashSet<MarkedBlock*>& set = heap.objectSpace().blocks().set();

MarkedBlock* candidate = MarkedBlock::blockFor(pointer);
if (filter.ruleOut(bitwise_cast<Bits>(candidate))) {
if (filter.ruleOut(bitwise_cast<uintptr_t>(candidate))) {
ASSERT(!candidate || !set.contains(candidate));
return false;
}
Expand All @@ -170,7 +170,7 @@ class HeapUtil {

// This does not find the cell if the pointer is pointing at the middle of a JSCell.
static bool isValueGCObject(
Heap& heap, TinyBloomFilter filter, JSValue value)
Heap& heap, TinyBloomFilter<uintptr_t> filter, JSValue value)
{
ASSERT(heap.objectSpace().preciseAllocationSet());
if (!value.isCell())
Expand Down
12 changes: 6 additions & 6 deletions Source/JavaScriptCore/heap/MarkedBlockSet.h
Expand Up @@ -38,19 +38,19 @@ class MarkedBlockSet {
void add(MarkedBlock*);
void remove(MarkedBlock*);

TinyBloomFilter filter() const;
TinyBloomFilter<uintptr_t> filter() const;
const HashSet<MarkedBlock*>& set() const;

private:
void recomputeFilter();

TinyBloomFilter m_filter;
TinyBloomFilter<uintptr_t> m_filter;
HashSet<MarkedBlock*> m_set;
};

inline void MarkedBlockSet::add(MarkedBlock* block)
{
m_filter.add(reinterpret_cast<Bits>(block));
m_filter.add(reinterpret_cast<uintptr_t>(block));
m_set.add(block);
}

Expand All @@ -64,13 +64,13 @@ inline void MarkedBlockSet::remove(MarkedBlock* block)

inline void MarkedBlockSet::recomputeFilter()
{
TinyBloomFilter filter;
TinyBloomFilter<uintptr_t> filter;
for (HashSet<MarkedBlock*>::iterator it = m_set.begin(); it != m_set.end(); ++it)
filter.add(reinterpret_cast<Bits>(*it));
filter.add(reinterpret_cast<uintptr_t>(*it));
m_filter = filter;
}

inline TinyBloomFilter MarkedBlockSet::filter() const
inline TinyBloomFilter<uintptr_t> MarkedBlockSet::filter() const
{
return m_filter;
}
Expand Down
18 changes: 11 additions & 7 deletions Source/JavaScriptCore/heap/TinyBloomFilter.h
Expand Up @@ -27,8 +27,7 @@

namespace JSC {

typedef uintptr_t Bits;

template <typename Bits = uintptr_t>
class TinyBloomFilter {
public:
TinyBloomFilter() = default;
Expand All @@ -44,22 +43,26 @@ class TinyBloomFilter {
Bits m_bits { 0 };
};

inline TinyBloomFilter::TinyBloomFilter(Bits bits)
template <typename Bits>
inline TinyBloomFilter<Bits>::TinyBloomFilter(Bits bits)
: m_bits(bits)
{
}

inline void TinyBloomFilter::add(Bits bits)
template <typename Bits>
inline void TinyBloomFilter<Bits>::add(Bits bits)
{
m_bits |= bits;
}

inline void TinyBloomFilter::add(TinyBloomFilter& other)
template <typename Bits>
inline void TinyBloomFilter<Bits>::add(TinyBloomFilter& other)
{
m_bits |= other.m_bits;
}

inline bool TinyBloomFilter::ruleOut(Bits bits) const
template <typename Bits>
inline bool TinyBloomFilter<Bits>::ruleOut(Bits bits) const
{
if (!bits)
return true;
Expand All @@ -70,7 +73,8 @@ inline bool TinyBloomFilter::ruleOut(Bits bits) const
return false;
}

inline void TinyBloomFilter::reset()
template <typename Bits>
inline void TinyBloomFilter<Bits>::reset()
{
m_bits = 0;
}
Expand Down
18 changes: 16 additions & 2 deletions Source/JavaScriptCore/jit/AssemblyHelpers.cpp
Expand Up @@ -332,7 +332,8 @@ void AssemblyHelpers::emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, Trust
{
const Structure* structurePtr = reinterpret_cast<const Structure*>(structure.m_value);
#if USE(JSVALUE64)
jit.store64(TrustedImm64(structurePtr->idBlob()), MacroAssembler::Address(dest, JSCell::structureIDOffset()));
jit.store32(TrustedImm32(structurePtr->id().bits()), MacroAssembler::Address(dest, JSCell::structureIDOffset()));
jit.store32(TrustedImm32(structurePtr->typeInfoBlob()), MacroAssembler::Address(dest, JSCell::indexingTypeAndMiscOffset()));
if (ASSERT_ENABLED) {
Jump correctStructure = jit.branch32(Equal, MacroAssembler::Address(dest, JSCell::structureIDOffset()), TrustedImm32(structurePtr->id().bits()));
jit.abortWithReason(AHStructureIDIsValid);
Expand All @@ -352,7 +353,7 @@ void AssemblyHelpers::emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, Trust
}
#else
// Do a 32-bit wide store to initialize the cell's fields.
jit.store32(TrustedImm32(structurePtr->objectInitializationBlob()), MacroAssembler::Address(dest, JSCell::indexingTypeAndMiscOffset()));
jit.store32(TrustedImm32(structurePtr->typeInfoBlob()), MacroAssembler::Address(dest, JSCell::indexingTypeAndMiscOffset()));
jit.storePtr(structure, MacroAssembler::Address(dest, JSCell::structureIDOffset()));
#endif
}
Expand Down Expand Up @@ -428,6 +429,19 @@ void AssemblyHelpers::emitLoadStructure(VM&, RegisterID source, RegisterID dest)
emitNonNullDecodeZeroExtendedStructureID(dest, dest);
}

void AssemblyHelpers::emitEncodeStructureID(RegisterID source, RegisterID dest)
{
#if ENABLE(STRUCTURE_ID_WITH_SHIFT)
urshift64(source, TrustedImm32(StructureID::encodeShiftAmount), dest);
#elif CPU(ADDRESS64)
move(source, dest);
static_assert(StructureID::structureIDMask <= UINT32_MAX);
and64(TrustedImm32(static_cast<uint32_t>(StructureID::structureIDMask)), dest);
#else
move(source, dest);
#endif
}

void AssemblyHelpers::emitLoadPrototype(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, JumpList& slowPath)
{
ASSERT(resultRegs.payloadGPR() != objectGPR);
Expand Down

0 comments on commit 771382d

Please sign in to comment.