Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (295007 => 295008)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2022-05-29 03:23:06 UTC (rev 295008)
@@ -1176,7 +1176,6 @@
runtime/StructureCache.h
runtime/StructureChain.h
runtime/StructureID.h
- runtime/StructureIDBlob.h
runtime/StructureInlines.h
runtime/StructureRareData.h
runtime/StructureRareDataInlines.h
@@ -1193,6 +1192,7 @@
runtime/ThrowScope.h
runtime/ToNativeFromValue.h
runtime/TypeError.h
+ runtime/TypeInfoBlob.h
runtime/TypeSet.h
runtime/TypedArrayAdaptersForwardDeclarations.h
runtime/TypedArrayAdaptors.h
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (295007 => 295008)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2022-05-29 03:23:06 UTC (rev 295008)
@@ -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, ); }; };
@@ -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>"; };
@@ -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 */,
@@ -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 */,
Modified: trunk/Source/_javascript_Core/bytecode/GetByValHistory.h (295007 => 295008)
--- trunk/Source/_javascript_Core/bytecode/GetByValHistory.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/bytecode/GetByValHistory.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -47,7 +47,7 @@
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)) {
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -11106,7 +11106,7 @@
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();
@@ -11317,7 +11317,7 @@
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())));
@@ -14886,7 +14886,7 @@
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())));
@@ -14935,7 +14935,7 @@
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())));
Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -76,7 +76,7 @@
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());
Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (295007 => 295008)
--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -147,7 +147,6 @@
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()) \
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -16839,10 +16839,21 @@
{
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()) {
@@ -16850,7 +16861,7 @@
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);
Modified: trunk/Source/_javascript_Core/heap/ConservativeRoots.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/heap/ConservativeRoots.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/heap/ConservativeRoots.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -63,7 +63,7 @@
}
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);
@@ -94,7 +94,7 @@
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)
Modified: trunk/Source/_javascript_Core/heap/ConservativeRoots.h (295007 => 295008)
--- trunk/Source/_javascript_Core/heap/ConservativeRoots.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/heap/ConservativeRoots.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -48,7 +48,7 @@
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&);
Modified: trunk/Source/_javascript_Core/heap/HeapSnapshot.h (295007 => 295008)
--- trunk/Source/_javascript_Core/heap/HeapSnapshot.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/heap/HeapSnapshot.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -52,7 +52,7 @@
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 };
Modified: trunk/Source/_javascript_Core/heap/HeapUtil.h (295007 => 295008)
--- trunk/Source/_javascript_Core/heap/HeapUtil.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/heap/HeapUtil.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -46,7 +46,7 @@
// 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();
@@ -86,7 +86,7 @@
// 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));
@@ -95,7 +95,7 @@
}
}
- if (filter.ruleOut(bitwise_cast<Bits>(candidate))) {
+ if (filter.ruleOut(bitwise_cast<uintptr_t>(candidate))) {
ASSERT(!candidate || !set.contains(candidate));
return;
}
@@ -134,7 +134,7 @@
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()) {
@@ -148,7 +148,7 @@
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;
}
@@ -170,7 +170,7 @@
// 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())
Modified: trunk/Source/_javascript_Core/heap/MarkedBlockSet.h (295007 => 295008)
--- trunk/Source/_javascript_Core/heap/MarkedBlockSet.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/heap/MarkedBlockSet.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -38,19 +38,19 @@
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);
}
@@ -64,13 +64,13 @@
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;
}
Modified: trunk/Source/_javascript_Core/heap/TinyBloomFilter.h (295007 => 295008)
--- trunk/Source/_javascript_Core/heap/TinyBloomFilter.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/heap/TinyBloomFilter.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -27,8 +27,7 @@
namespace JSC {
-typedef uintptr_t Bits;
-
+template <typename Bits = uintptr_t>
class TinyBloomFilter {
public:
TinyBloomFilter() = default;
@@ -44,22 +43,26 @@
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;
@@ -70,7 +73,8 @@
return false;
}
-inline void TinyBloomFilter::reset()
+template <typename Bits>
+inline void TinyBloomFilter<Bits>::reset()
{
m_bits = 0;
}
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -332,7 +332,8 @@
{
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);
@@ -352,7 +353,7 @@
}
#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
}
@@ -428,6 +429,19 @@
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);
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (295007 => 295008)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -1613,6 +1613,7 @@
void emitNonNullDecodeZeroExtendedStructureID(RegisterID source, RegisterID dest);
void emitLoadStructure(VM&, RegisterID source, RegisterID dest);
void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, JumpList& slowPath);
+ void emitEncodeStructureID(RegisterID source, RegisterID dest);
void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID)
{
@@ -1621,17 +1622,16 @@
void emitStoreStructureWithTypeInfo(RegisterID structure, RegisterID dest, RegisterID scratch)
{
+ // Store the StructureID
#if USE(JSVALUE64)
- load64(MacroAssembler::Address(structure, Structure::structureIDOffset()), scratch);
- store64(scratch, MacroAssembler::Address(dest, JSCell::structureIDOffset()));
+ emitEncodeStructureID(structure, scratch);
+ store32(scratch, MacroAssembler::Address(dest, JSCell::structureIDOffset()));
#else
+ storePtr(structure, MacroAssembler::Address(dest, JSCell::structureIDOffset()));
+#endif
// Store all the info flags using a single 32-bit wide load and store.
load32(MacroAssembler::Address(structure, Structure::indexingModeIncludingHistoryOffset()), scratch);
store32(scratch, MacroAssembler::Address(dest, JSCell::indexingTypeAndMiscOffset()));
-
- // Store the StructureID
- storePtr(structure, MacroAssembler::Address(dest, JSCell::structureIDOffset()));
-#endif
}
static void emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, TrustedImmPtr structure, RegisterID dest);
@@ -1914,7 +1914,30 @@
for (unsigned i = 0; i < outOfLineCapacity; ++i)
storeTrustedValue(JSValue(), Address(butterflyGPR, -sizeof(IndexingHeader) - (i + 1) * sizeof(EncodedJSValue)));
}
-
+
+ void loadCompactPtr(Address address, GPRReg dest)
+ {
+#if HAVE(36BIT_ADDRESS)
+ load32(address, dest);
+ lshift64(TrustedImm32(4), dest);
+#else
+ loadPtr(address, dest);
+#endif
+ }
+
+ Jump branchCompactPtr(RelationalCondition cond, GPRReg left, Address right, GPRReg scratch)
+ {
+#if HAVE(36BIT_ADDRESS)
+ ASSERT(left != scratch);
+ load32(right, scratch);
+ lshift64(TrustedImm32(4), scratch);
+ return branchPtr(cond, left, Address(scratch));
+#else
+ UNUSED_PARAM(scratch);
+ return branchPtr(cond, left, right);
+#endif
+ }
+
#if USE(JSVALUE64)
void wangsInt64Hash(GPRReg inputAndResult, GPRReg scratch);
#endif
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -1740,7 +1740,7 @@
// Structure check covers var injection since we don't cache structures for anything but the GlobalObject. Additionally, resolve_scope handles checking for the var injection.
jit.loadPtr(Address(metadataGPR, OpGetFromScope::Metadata::offsetOfStructure()), scratchGPR);
slowCase.append(jit.branchTestPtr(Zero, scratchGPR));
- jit.load32(Address(scratchGPR, Structure::structureIDOffset()), scratchGPR);
+ jit.emitEncodeStructureID(scratchGPR, scratchGPR);
slowCase.append(jit.branch32(NotEqual, Address(scopeGPR, JSCell::structureIDOffset()), scratchGPR));
jit.jitAssert(scopedLambda<Jump(void)>([&] () -> Jump {
@@ -1913,7 +1913,7 @@
loadPtrFromMetadata(bytecode, OpPutToScope::Metadata::offsetOfStructure(), scratchGPR1);
emitGetVirtualRegisterPayload(scope, scopeGPR);
addSlowCase(branchTestPtr(Zero, scratchGPR1));
- load32(Address(scratchGPR1, Structure::structureIDOffset()), scratchGPR1);
+ emitEncodeStructureID(scratchGPR1, scratchGPR1);
addSlowCase(branch32(NotEqual, Address(scopeGPR, JSCell::structureIDOffset()), scratchGPR1));
emitGetVirtualRegister(value, valueJSR);
Modified: trunk/Source/_javascript_Core/runtime/ClassInfo.h (295007 => 295008)
--- trunk/Source/_javascript_Core/runtime/ClassInfo.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/runtime/ClassInfo.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -24,8 +24,15 @@
#include "ConstructData.h"
#include "JSCast.h"
+#include <wtf/CompactPtr.h>
#include <wtf/PtrTag.h>
+#if HAVE(36BIT_ADDRESS)
+#define CLASS_INFO_ALIGNMENT alignas(16)
+#else
+#define CLASS_INFO_ALIGNMENT
+#endif
+
namespace WTF {
class PrintStream;
};
@@ -172,7 +179,7 @@
ClassName::TypedArrayStorageType, \
sizeof(ClassName),
-struct ClassInfo {
+struct CLASS_INFO_ALIGNMENT ClassInfo {
using CheckJSCastSnippetFunctionPtr = Ref<Snippet> (*)(void);
// A string denoting the class name. Example: "Window".
Modified: trunk/Source/_javascript_Core/runtime/SamplingProfiler.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/runtime/SamplingProfiler.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/runtime/SamplingProfiler.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -468,7 +468,7 @@
// This function needs to be called from the JSC execution thread.
RELEASE_ASSERT(m_lock.isLocked());
- TinyBloomFilter filter = m_vm.heap.objectSpace().blocks().filter();
+ TinyBloomFilter<uintptr_t> filter = m_vm.heap.objectSpace().blocks().filter();
for (UnprocessedStackTrace& unprocessedStackTrace : m_unprocessedStackTraces) {
m_stackTraces.append(StackTrace());
Modified: trunk/Source/_javascript_Core/runtime/Structure.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/runtime/Structure.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/runtime/Structure.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -197,15 +197,15 @@
Structure::Structure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity)
: JSCell(vm, vm.structureStructure.get())
- , m_blob(StructureID::encode(this), indexingType, typeInfo)
+ , m_blob(indexingType, typeInfo)
, m_outOfLineTypeFlags(typeInfo.outOfLineTypeFlags())
, m_inlineCapacity(inlineCapacity)
, m_bitField(0)
+ , m_propertyHash(0)
, m_globalObject(vm, this, globalObject, WriteBarrier<JSGlobalObject>::MayBeNull)
, m_prototype(vm, this, prototype)
, m_classInfo(classInfo)
, m_transitionWatchpointSet(IsWatched)
- , m_propertyHash(0)
{
setDictionaryKind(NoneDictionaryKind);
setIsPinnedPropertyTable(false);
@@ -244,10 +244,10 @@
: JSCell(CreatingEarlyCell)
, m_inlineCapacity(0)
, m_bitField(0)
+ , m_propertyHash(0)
, m_prototype(vm, this, jsNull())
, m_classInfo(info())
, m_transitionWatchpointSet(IsWatched)
- , m_propertyHash(0)
{
setDictionaryKind(NoneDictionaryKind);
setIsPinnedPropertyTable(false);
@@ -268,7 +268,7 @@
setMaxOffset(vm, invalidOffset);
TypeInfo typeInfo = TypeInfo(StructureType, StructureFlags);
- m_blob = StructureIDBlob(StructureID::encode(this), 0, typeInfo);
+ m_blob = TypeInfoBlob(0, typeInfo);
m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
@@ -284,11 +284,11 @@
: JSCell(vm, vm.structureStructure.get())
, m_inlineCapacity(previous->m_inlineCapacity)
, m_bitField(0)
+ , m_propertyHash(previous->m_propertyHash)
+ , m_seenProperties(previous->m_seenProperties)
, m_prototype(vm, this, previous->m_prototype.get())
, m_classInfo(previous->m_classInfo)
, m_transitionWatchpointSet(IsWatched)
- , m_propertyHash(previous->m_propertyHash)
- , m_seenProperties(previous->m_seenProperties)
{
setDictionaryKind(previous->dictionaryKind());
setIsPinnedPropertyTable(false);
@@ -309,7 +309,7 @@
setMaxOffset(vm, invalidOffset);
TypeInfo typeInfo = previous->typeInfo();
- m_blob = StructureIDBlob(StructureID::encode(this), previous->indexingModeIncludingHistory(), typeInfo);
+ m_blob = TypeInfoBlob(previous->indexingModeIncludingHistory(), typeInfo);
m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
ASSERT(!previous->typeInfo().structureIsImmortal());
Modified: trunk/Source/_javascript_Core/runtime/Structure.h (295007 => 295008)
--- trunk/Source/_javascript_Core/runtime/Structure.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/runtime/Structure.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -38,14 +38,15 @@
#include "PropertyNameArray.h"
#include "PropertyOffset.h"
#include "PutPropertySlot.h"
-#include "StructureIDBlob.h"
#include "StructureRareData.h"
#include "StructureTransitionTable.h"
-#include "TinyBloomFilter.h"
+#include "TypeInfoBlob.h"
#include "Watchpoint.h"
#include "WriteBarrierInlines.h"
#include <wtf/Atomics.h>
#include <wtf/CompactPointerTuple.h>
+#include <wtf/CompactPtr.h>
+#include <wtf/CompactRefPtr.h>
#include <wtf/PrintStream.h>
namespace WTF {
@@ -230,10 +231,10 @@
void validateFlags();
public:
- StructureID id() const { ASSERT(m_blob.structureID() == StructureID::encode(this)); return m_blob.structureID(); }
- int32_t objectInitializationBlob() const { return m_blob.blobExcludingStructureID(); }
- int64_t idBlob() const { return m_blob.blob(); }
+ StructureID id() const { return StructureID::encode(this); }
+ int32_t typeInfoBlob() const { return m_blob.blob(); }
+
bool isProxy() const
{
JSType type = m_blob.type();
@@ -330,7 +331,7 @@
// Type accessors.
TypeInfo typeInfo() const { return m_blob.typeInfo(m_outOfLineTypeFlags); }
bool isObject() const { return typeInfo().isObject(); }
- const ClassInfo* classInfoForCells() const { return m_classInfo; }
+ const ClassInfo* classInfoForCells() const { return m_classInfo.get(); }
protected:
// You probably want typeInfo().type()
JSType type() { return JSCell::type(); }
@@ -649,11 +650,6 @@
}
void cacheSpecialProperty(JSGlobalObject*, VM&, JSValue, CachedSpecialPropertyKey, const PropertySlot&);
- static ptrdiff_t structureIDOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_blob) + StructureIDBlob::structureIDOffset();
- }
-
static ptrdiff_t prototypeOffset()
{
return OBJECT_OFFSETOF(Structure, m_prototype);
@@ -676,7 +672,7 @@
static ptrdiff_t indexingModeIncludingHistoryOffset()
{
- return OBJECT_OFFSETOF(Structure, m_blob) + StructureIDBlob::indexingModeIncludingHistoryOffset();
+ return OBJECT_OFFSETOF(Structure, m_blob) + TypeInfoBlob::indexingModeIncludingHistoryOffset();
}
static ptrdiff_t propertyTableUnsafeOffset()
@@ -957,7 +953,7 @@
// These need to be properly aligned at the beginning of the 'Structure'
// part of the object.
- StructureIDBlob m_blob;
+ TypeInfoBlob m_blob;
TypeInfo::OutOfLineTypeFlags m_outOfLineTypeFlags;
uint8_t m_inlineCapacity;
@@ -966,6 +962,13 @@
uint32_t m_bitField;
+ uint16_t m_transitionOffset;
+ uint16_t m_maxOffset;
+
+ uint32_t m_propertyHash;
+ TinyBloomFilter<CompactPtr<UniquedStringImpl>::StorageType> m_seenProperties;
+
+
WriteBarrier<JSGlobalObject> m_globalObject;
WriteBarrier<Unknown> m_prototype;
mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
@@ -972,9 +975,9 @@
WriteBarrier<JSCell> m_previousOrRareData;
- RefPtr<UniquedStringImpl> m_transitionPropertyName;
+ CompactRefPtr<UniquedStringImpl> m_transitionPropertyName;
- const ClassInfo* m_classInfo;
+ CompactPtr<const ClassInfo> m_classInfo;
StructureTransitionTable m_transitionTable;
@@ -986,12 +989,6 @@
static_assert(firstOutOfLineOffset < 256);
- uint16_t m_transitionOffset;
- uint16_t m_maxOffset;
-
- uint32_t m_propertyHash;
- TinyBloomFilter m_seenProperties;
-
friend class VMInspector;
friend class JSDollarVMHelper;
friend class Integrity::Analyzer;
Deleted: trunk/Source/_javascript_Core/runtime/StructureIDBlob.h (295007 => 295008)
--- trunk/Source/_javascript_Core/runtime/StructureIDBlob.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/runtime/StructureIDBlob.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2014-2017 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. AND ITS CONTRIBUTORS ``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 ITS 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 "CellState.h"
-#include "IndexingType.h"
-#include "JSTypeInfo.h"
-#include "StructureID.h"
-
-namespace JSC {
-
-class StructureIDBlob {
- friend class LLIntOffsetsExtractor;
-public:
- StructureIDBlob() = default;
-
- StructureIDBlob(StructureID structureID, IndexingType indexingModeIncludingHistory, const TypeInfo& typeInfo)
- {
- u.fields.structureID = structureID;
- u.fields.indexingModeIncludingHistory = indexingModeIncludingHistory;
- u.fields.type = typeInfo.type();
- u.fields.inlineTypeFlags = typeInfo.inlineTypeFlags();
- u.fields.defaultCellState = CellState::DefinitelyWhite;
- }
-
- void operator=(const StructureIDBlob& other) { u.doubleWord = other.u.doubleWord; }
-
- StructureID structureID() const { return u.fields.structureID; }
- IndexingType indexingModeIncludingHistory() const { return u.fields.indexingModeIncludingHistory; }
- Dependency fencedIndexingModeIncludingHistory(IndexingType& indexingType)
- {
- return Dependency::loadAndFence(&u.fields.indexingModeIncludingHistory, indexingType);
- }
- void setIndexingModeIncludingHistory(IndexingType indexingModeIncludingHistory) { u.fields.indexingModeIncludingHistory = indexingModeIncludingHistory; }
- JSType type() const { return u.fields.type; }
- TypeInfo::InlineTypeFlags inlineTypeFlags() const { return u.fields.inlineTypeFlags; }
-
- TypeInfo typeInfo(TypeInfo::OutOfLineTypeFlags outOfLineTypeFlags) const { return TypeInfo(type(), inlineTypeFlags(), outOfLineTypeFlags); }
-
- int32_t blobExcludingStructureID() const { return u.words.word2; }
- int64_t blob() const { return u.doubleWord; }
-
- static ptrdiff_t structureIDOffset()
- {
- return OBJECT_OFFSETOF(StructureIDBlob, u.fields.structureID);
- }
-
- static ptrdiff_t indexingModeIncludingHistoryOffset()
- {
- return OBJECT_OFFSETOF(StructureIDBlob, u.fields.indexingModeIncludingHistory);
- }
-
-private:
- union Data {
- struct {
- // FIXME: We should remove this since the structureID can be directly computed from the Structure*
- StructureID structureID;
- IndexingType indexingModeIncludingHistory;
- JSType type;
- TypeInfo::InlineTypeFlags inlineTypeFlags;
- CellState defaultCellState;
- } fields;
- struct {
- int32_t word1;
- int32_t word2;
- } words;
- int64_t doubleWord;
-
- Data() { doubleWord = 0xbbadbeef; }
- };
-
- Data u;
-};
-
-} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/StructureInlines.h (295007 => 295008)
--- trunk/Source/_javascript_Core/runtime/StructureInlines.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/runtime/StructureInlines.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -33,6 +33,7 @@
#include "Structure.h"
#include "StructureChain.h"
#include "StructureRareDataInlines.h"
+#include <wtf/CompactRefPtr.h>
#include <wtf/Threading.h>
namespace JSC {
@@ -164,7 +165,7 @@
ASSERT(!isCompilationThread());
ASSERT(structure()->classInfoForCells() == info());
- if (m_seenProperties.ruleOut(bitwise_cast<uintptr_t>(propertyName.uid())))
+ if (m_seenProperties.ruleOut(CompactPtr<UniquedStringImpl>::encode(propertyName.uid())))
return invalidOffset;
PropertyTable* propertyTable = ensurePropertyTableIfNotEmpty(vm);
@@ -489,7 +490,7 @@
PropertyOffset newOffset = table->nextOffset(m_inlineCapacity);
m_propertyHash = m_propertyHash ^ rep->existingSymbolAwareHash();
- m_seenProperties.add(bitwise_cast<uintptr_t>(rep));
+ m_seenProperties.add(CompactPtr<UniquedStringImpl>::encode(rep));
auto [offset, attribute, result] = table->add(vm, PropertyTableEntry(rep, newOffset, attributes));
ASSERT_UNUSED(result, result);
Copied: trunk/Source/_javascript_Core/runtime/TypeInfoBlob.h (from rev 295007, trunk/Source/_javascript_Core/runtime/StructureIDBlob.h) (0 => 295008)
--- trunk/Source/_javascript_Core/runtime/TypeInfoBlob.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/TypeInfoBlob.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014-2017 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. AND ITS CONTRIBUTORS ``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 ITS 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 "CellState.h"
+#include "IndexingType.h"
+#include "JSTypeInfo.h"
+#include "StructureID.h"
+
+namespace JSC {
+
+class TypeInfoBlob {
+ friend class LLIntOffsetsExtractor;
+public:
+ TypeInfoBlob() = default;
+
+ TypeInfoBlob(IndexingType indexingModeIncludingHistory, const TypeInfo& typeInfo)
+ {
+ u.fields.indexingModeIncludingHistory = indexingModeIncludingHistory;
+ u.fields.type = typeInfo.type();
+ u.fields.inlineTypeFlags = typeInfo.inlineTypeFlags();
+ u.fields.defaultCellState = CellState::DefinitelyWhite;
+ }
+
+ void operator=(const TypeInfoBlob& other) { u.word = other.u.word; }
+
+ IndexingType indexingModeIncludingHistory() const { return u.fields.indexingModeIncludingHistory; }
+ Dependency fencedIndexingModeIncludingHistory(IndexingType& indexingType)
+ {
+ return Dependency::loadAndFence(&u.fields.indexingModeIncludingHistory, indexingType);
+ }
+ void setIndexingModeIncludingHistory(IndexingType indexingModeIncludingHistory) { u.fields.indexingModeIncludingHistory = indexingModeIncludingHistory; }
+ JSType type() const { return u.fields.type; }
+ TypeInfo::InlineTypeFlags inlineTypeFlags() const { return u.fields.inlineTypeFlags; }
+
+ TypeInfo typeInfo(TypeInfo::OutOfLineTypeFlags outOfLineTypeFlags) const { return TypeInfo(type(), inlineTypeFlags(), outOfLineTypeFlags); }
+
+ int32_t blob() const { return u.word; }
+
+ static ptrdiff_t indexingModeIncludingHistoryOffset()
+ {
+ return OBJECT_OFFSETOF(TypeInfoBlob, u.fields.indexingModeIncludingHistory);
+ }
+
+private:
+ union Data {
+ struct {
+ IndexingType indexingModeIncludingHistory;
+ JSType type;
+ TypeInfo::InlineTypeFlags inlineTypeFlags;
+ CellState defaultCellState;
+ } fields;
+ int32_t word;
+
+ Data() { word = 0xbbadbeef; }
+ };
+
+ Data u;
+};
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (295007 => 295008)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -268,7 +268,7 @@
stackLimitGPRIsClobbered = true;
jit.emitLoadStructure(vm, scratchGPR, scratchGPR);
- jit.loadPtr(CCallHelpers::Address(scratchGPR, Structure::classInfoOffset()), scratchGPR);
+ jit.loadCompactPtr(CCallHelpers::Address(scratchGPR, Structure::classInfoOffset()), scratchGPR);
static_assert(std::is_final<WebAssemblyFunction>::value, "We do not check for subtypes below");
static_assert(std::is_final<WebAssemblyWrapperFunction>::value, "We do not check for subtypes below");
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (295007 => 295008)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2022-05-29 03:23:06 UTC (rev 295008)
@@ -811,6 +811,8 @@
FE35D09227DC5ECC009DFA5B /* StackCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE35D09127DC5ECC009DFA5B /* StackCheck.cpp */; };
FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; };
FEEA4DF9216D7BE400AC0602 /* StackPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEEA4DF8216D7BE400AC0602 /* StackPointer.cpp */; };
+ FF895F11282AB96400E7BAE8 /* CompactRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = FF895F10282AB96400E7BAE8 /* CompactRefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FFEE46F42825DF80003BC981 /* CompactPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = FFEE46F32825DF80003BC981 /* CompactPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
@@ -1714,6 +1716,8 @@
FEEA4DF8216D7BE400AC0602 /* StackPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackPointer.cpp; sourceTree = "<group>"; };
FEF295BF20B49DCB00CF283A /* UTF8ConversionError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UTF8ConversionError.h; sourceTree = "<group>"; };
FF0A436588954F3CB07DBECA /* StdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StdList.h; sourceTree = "<group>"; };
+ FF895F10282AB96400E7BAE8 /* CompactRefPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompactRefPtr.h; sourceTree = "<group>"; };
+ FFEE46F32825DF80003BC981 /* CompactPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompactPtr.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1930,6 +1934,8 @@
0F66B2811DC97BAB004A1D3F /* ClockType.h */,
0FC4EDE51696149600F65041 /* CommaPrinter.h */,
E3CF76902115D6BA0091DE48 /* CompactPointerTuple.h */,
+ FFEE46F32825DF80003BC981 /* CompactPtr.h */,
+ FF895F10282AB96400E7BAE8 /* CompactRefPtr.h */,
E38020DB2401C0930037CA9E /* CompactRefPtrTuple.h */,
9B96E9B324FF77B8001756C3 /* CompactUniquePtrTuple.h */,
0F8F2B8F172E00F0007DBDA5 /* CompilationThread.cpp */,
@@ -2861,6 +2867,8 @@
DDF307F427C086EA006A526F /* Collator.h in Headers */,
DD3DC91627A4BF8E007E5B61 /* CommaPrinter.h in Headers */,
DD3DC8F627A4BF8E007E5B61 /* CompactPointerTuple.h in Headers */,
+ FFEE46F42825DF80003BC981 /* CompactPtr.h in Headers */,
+ FF895F11282AB96400E7BAE8 /* CompactRefPtr.h in Headers */,
DD3DC93927A4BF8E007E5B61 /* CompactRefPtrTuple.h in Headers */,
DD3DC93527A4BF8E007E5B61 /* CompactUniquePtrTuple.h in Headers */,
DD3DC90727A4BF8E007E5B61 /* CompilationThread.h in Headers */,
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (295007 => 295008)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2022-05-29 03:23:06 UTC (rev 295008)
@@ -35,6 +35,8 @@
ClockType.h
CommaPrinter.h
CompactPointerTuple.h
+ CompactPtr.h
+ CompactRefPtr.h
CompactRefPtrTuple.h
CompactUniquePtrTuple.h
CompilationThread.h
Added: trunk/Source/WTF/wtf/CompactPtr.h (0 => 295008)
--- trunk/Source/WTF/wtf/CompactPtr.h (rev 0)
+++ trunk/Source/WTF/wtf/CompactPtr.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2022 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 <cstdint>
+#include <utility>
+#include <wtf/RawPtrTraits.h>
+#include <wtf/StdLibExtras.h>
+
+#if OS(DARWIN)
+#include <mach/vm_param.h>
+#endif
+
+namespace WTF {
+
+#if CPU(ADDRESS64)
+#if CPU(ARM64) && OS(DARWIN)
+#if MACH_VM_MAX_ADDRESS_RAW < (1ULL << 36)
+#define HAVE_36BIT_ADDRESS 1
+#endif
+#endif
+#endif // CPU(ADDRESS64)
+
+template <typename T>
+class CompactPtr {
+ WTF_MAKE_FAST_ALLOCATED;
+
+public:
+#if HAVE(36BIT_ADDRESS)
+ // The CompactPtr algorithm relies on being able to shift
+ // a 36-bit address right by 4 in order to fit in 32-bits.
+ // The only way this is an ok thing to do without information
+ // loss is if the if the address is always 16 bytes aligned i.e.
+ // the lower 4 bits is always 0.
+ using StorageType = uint32_t;
+#else
+ using StorageType = uintptr_t;
+#endif
+ static constexpr bool isCompactedType = true;
+
+ ALWAYS_INLINE constexpr CompactPtr() = default;
+
+ ALWAYS_INLINE constexpr CompactPtr(std::nullptr_t) { }
+
+ ALWAYS_INLINE CompactPtr(T* ptr) { set(ptr); }
+
+ ALWAYS_INLINE constexpr CompactPtr(const CompactPtr& o) : m_ptr(o.m_ptr) { }
+
+ template <typename X>
+ ALWAYS_INLINE constexpr CompactPtr(const CompactPtr<X>& o) : m_ptr(o.m_ptr) { static_assert(std::is_convertible_v<X*, T*>); }
+
+ ALWAYS_INLINE CompactPtr(CompactPtr&& o) { swap(o); }
+
+ template <typename X>
+ ALWAYS_INLINE CompactPtr(CompactPtr<X>&& o)
+ : m_ptr(o.m_ptr)
+ {
+ static_assert(std::is_convertible_v<X*, T*>);
+ std::exchange(o.m_ptr, 0);
+ }
+
+ ALWAYS_INLINE ~CompactPtr() = default;
+
+ T& operator*() const { return *get(); }
+
+ ALWAYS_INLINE T* operator->() const { return get(); }
+
+ bool operator!() const { return !get(); }
+
+ explicit operator bool() const { return !!get(); }
+
+ CompactPtr<T>& operator=(std::nullptr_t)
+ {
+ exchange(nullptr);
+ return *this;
+ }
+
+ CompactPtr<T>& operator=(const CompactPtr& o)
+ {
+ CompactPtr copy(o);
+ swap(copy);
+ return *this;
+ }
+
+ template <typename X>
+ CompactPtr<T>& operator=(const CompactPtr<X>& o)
+ {
+ static_assert(std::is_convertible_v<X*, T*>);
+ CompactPtr copy(o);
+ swap(copy);
+ return *this;
+ }
+
+ CompactPtr<T>& operator=(T* optr)
+ {
+ CompactPtr copy(optr);
+ swap(copy);
+ return *this;
+ }
+
+ CompactPtr<T>& operator=(CompactPtr&& o)
+ {
+ CompactPtr moved(WTFMove(o));
+ swap(moved);
+ return *this;
+ }
+
+ template <typename X>
+ CompactPtr<T>& operator=(CompactPtr<X>&& o)
+ {
+ static_assert(std::is_convertible_v<X*, T*>);
+ CompactPtr moved(WTFMove(o));
+ swap(moved);
+ return *this;
+ }
+
+ T* get() const { return decode(m_ptr); }
+
+ void set(T* ptr) { m_ptr = encode(ptr); }
+
+ template <class U>
+ T* exchange(U&& newValue)
+ {
+ T* oldValue = get();
+ set(std::forward<U>(newValue));
+ return oldValue;
+ }
+
+ void swap(nullptr_t) { set(nullptr); }
+
+ void swap(CompactPtr& other) { std::swap(m_ptr, other.m_ptr); }
+
+ template <typename Other, typename = std::enable_if_t<Other::isCompactedType>>
+ void swap(Other& other)
+ {
+ T* t1 = get();
+ T* t2 = other.get();
+ set(t2);
+ other.set(t1);
+ }
+
+ void swap(T*& t2)
+ {
+ T* t1 = get();
+ std::swap(t1, t2);
+ set(t1);
+ }
+
+ static ALWAYS_INLINE constexpr StorageType encode(T* ptr)
+ {
+ uintptr_t intPtr = bitwise_cast<uintptr_t>(ptr);
+#if HAVE(36BIT_ADDRESS)
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(!(intPtr & alignmentMask));
+ StorageType encoded = static_cast<uint32_t>(intPtr >> bitsShift);
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(decode(encoded) == ptr);
+ return encoded;
+#else
+ return intPtr;
+#endif
+ }
+
+ ALWAYS_INLINE constexpr T* decode(const StorageType& ptr) const
+ {
+#if HAVE(36BIT_ADDRESS)
+ return reinterpret_cast<T*>(static_cast<uintptr_t>(ptr) << bitsShift);
+#else
+ return reinterpret_cast<T*>(ptr);
+#endif
+ }
+
+private:
+ template <typename X>
+ friend class CompactPtr;
+
+ static constexpr uint32_t bitsShift = 4;
+ static constexpr uintptr_t alignmentMask = (1ull << bitsShift) - 1;
+
+ StorageType m_ptr { 0 };
+};
+
+template <typename T>
+struct GetPtrHelper<CompactPtr<T>> {
+ using PtrType = T*;
+ static T* getPtr(const CompactPtr<T>& p) { return const_cast<T*>(p.get()); }
+};
+
+template <typename T>
+struct IsSmartPtr<CompactPtr<T>> {
+ static constexpr bool value = true;
+};
+
+template <typename T>
+struct CompactPtrTraits {
+ template <typename U>
+ using RebindTraits = RawPtrTraits<U>;
+
+ using StorageType = CompactPtr<T>;
+
+ template <typename U>
+ static ALWAYS_INLINE T* exchange(StorageType& ptr, U&& newValue) { return ptr.exchange(newValue); }
+
+ template <typename Other>
+ static ALWAYS_INLINE void swap(StorageType& a, Other& b) { a.swap(b); }
+
+ static ALWAYS_INLINE T* unwrap(const StorageType& ptr) { return ptr.get(); }
+
+ static StorageType hashTableDeletedValue() { return bitwise_cast<StorageType>(static_cast<StorageType>(-1)); }
+ static ALWAYS_INLINE bool isHashTableDeletedValue(const StorageType& ptr) { return ptr == hashTableDeletedValue(); }
+};
+
+} // namespace WTF
+
+using WTF::CompactPtr;
+using WTF::CompactPtrTraits;
Copied: trunk/Source/WTF/wtf/CompactRefPtr.h (from rev 295007, trunk/Source/_javascript_Core/heap/HeapSnapshot.h) (0 => 295008)
--- trunk/Source/WTF/wtf/CompactRefPtr.h (rev 0)
+++ trunk/Source/WTF/wtf/CompactRefPtr.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 <wtf/CompactPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WTF {
+
+template <typename T>
+using CompactRefPtr = RefPtr<T, CompactPtrTraits<T>>;
+
+} // namespace WTF
+
+using WTF::CompactRefPtr;
Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (295007 => 295008)
--- trunk/Source/WTF/wtf/text/StringImpl.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -45,8 +45,14 @@
using namespace Unicode;
-static_assert(sizeof(StringImpl) == 2 * sizeof(int) + 2 * sizeof(void*), "StringImpl should stay small");
+#if HAVE(36BIT_ADDRESS)
+#define STRING_IMPL_SIZE(n) roundUpToMultipleOfImpl(16, n)
+#else
+#define STRING_IMPL_SIZE(n) n
+#endif
+static_assert(sizeof(StringImpl) == STRING_IMPL_SIZE(2 * sizeof(int) + 2 * sizeof(void*)), "StringImpl should stay small");
+
#if STRING_STATS
StringStats StringImpl::m_stringStats;
Modified: trunk/Source/WTF/wtf/text/StringImpl.h (295007 => 295008)
--- trunk/Source/WTF/wtf/text/StringImpl.h 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Source/WTF/wtf/text/StringImpl.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -26,6 +26,7 @@
#include <unicode/ustring.h>
#include <wtf/ASCIICType.h>
#include <wtf/CheckedArithmetic.h>
+#include <wtf/CompactPtr.h>
#include <wtf/DebugHeap.h>
#include <wtf/Expected.h>
#include <wtf/MathExtras.h>
@@ -48,6 +49,12 @@
@class NSString;
#endif
+#if HAVE(36BIT_ADDRESS)
+#define STRING_IMPL_ALIGNMENT alignas(16)
+#else
+#define STRING_IMPL_ALIGNMENT
+#endif
+
namespace JSC {
namespace LLInt { class Data; }
class LLIntOffsetsExtractor;
@@ -132,7 +139,7 @@
#endif
-class StringImplShape {
+class STRING_IMPL_ALIGNMENT StringImplShape {
WTF_MAKE_NONCOPYABLE(StringImplShape);
public:
static constexpr unsigned MaxLength = std::numeric_limits<int32_t>::max();
Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (295007 => 295008)
--- trunk/Tools/TestWebKitAPI/CMakeLists.txt 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt 2022-05-29 03:23:06 UTC (rev 295008)
@@ -29,6 +29,8 @@
Tests/WTF/BumpPointerAllocator.cpp
Tests/WTF/CString.cpp
Tests/WTF/CheckedArithmeticOperations.cpp
+ Tests/WTF/CompactPtr.cpp
+ Tests/WTF/CompactRefPtr.cpp
Tests/WTF/CompactRefPtrTuple.cpp
Tests/WTF/CompactUniquePtrTuple.cpp
Tests/WTF/ConcurrentPtrHashSet.cpp
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (295007 => 295008)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2022-05-29 03:23:06 UTC (rev 295008)
@@ -1167,6 +1167,8 @@
FE2D9474245EB2F400E48135 /* Bitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE2D9473245EB2DF00E48135 /* Bitmap.cpp */; };
FEC2A85424CE975F00ADBC35 /* DisallowVMEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC2A85324CE974E00ADBC35 /* DisallowVMEntry.cpp */; };
FEC2A85624CEB65F00ADBC35 /* PropertySlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEC2A85524CEB65F00ADBC35 /* PropertySlot.cpp */; };
+ FF10AAF92831B1E600B9875B /* CompactPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF10AAF82831B1E600B9875B /* CompactPtr.cpp */; };
+ FF5D0CB4283221AD00F3278A /* CompactRefPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FF5D0CB3283221AD00F3278A /* CompactRefPtr.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -3235,6 +3237,9 @@
FEB6F74E1B2BA44E009E4922 /* NakedPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NakedPtr.cpp; sourceTree = "<group>"; };
FEC2A85324CE974E00ADBC35 /* DisallowVMEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisallowVMEntry.cpp; sourceTree = "<group>"; };
FEC2A85524CEB65F00ADBC35 /* PropertySlot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertySlot.cpp; sourceTree = "<group>"; };
+ FF10AAF82831B1E600B9875B /* CompactPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompactPtr.cpp; sourceTree = "<group>"; };
+ FF25942A2834B7A7006892D6 /* AlignedRefLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlignedRefLogger.h; sourceTree = "<group>"; };
+ FF5D0CB3283221AD00F3278A /* CompactRefPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompactRefPtr.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -4655,6 +4660,8 @@
A7A966DA140ECCC8005EF9B4 /* CheckedArithmeticOperations.cpp */,
9BBCA4DE265ACA5B00DFE723 /* CheckedPtr.cpp */,
9BF00132267C4C5900DCFB3F /* CheckedRef.cpp */,
+ FF10AAF82831B1E600B9875B /* CompactPtr.cpp */,
+ FF5D0CB3283221AD00F3278A /* CompactRefPtr.cpp */,
E302BDA92404B92300865277 /* CompactRefPtrTuple.cpp */,
9B0C051824FDFB7000F2FE31 /* CompactUniquePtrTuple.cpp */,
0F30CB5B1FCE1792004B5323 /* ConcurrentPtrHashSet.cpp */,
@@ -4662,6 +4669,7 @@
278DE64B22B8D611004E0E7A /* CrossThreadCopier.cpp */,
51714EB91D087416004723C4 /* CrossThreadTask.cpp */,
26A2C72E15E2E73C005B1A14 /* CString.cpp */,
+ FF25942A2834B7A7006892D6 /* AlignedRefLogger.h */,
7AA021BA1AB09EA70052953F /* DateMath.cpp */,
1A3524A91D627BD40031729B /* DeletedAddressOfOperator.h */,
E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */,
@@ -5454,6 +5462,8 @@
7C83DEA01D0A590C00FEBCF3 /* CheckedArithmeticOperations.cpp in Sources */,
9BBCA4DF265ACA5B00DFE723 /* CheckedPtr.cpp in Sources */,
9BF00133267C4C5900DCFB3F /* CheckedRef.cpp in Sources */,
+ FF10AAF92831B1E600B9875B /* CompactPtr.cpp in Sources */,
+ FF5D0CB4283221AD00F3278A /* CompactRefPtr.cpp in Sources */,
E302BDAA2404B92400865277 /* CompactRefPtrTuple.cpp in Sources */,
9B0C051924FDFB7D00F2FE31 /* CompactUniquePtrTuple.cpp in Sources */,
0F30CB5C1FCE1796004B5323 /* ConcurrentPtrHashSet.cpp in Sources */,
Copied: trunk/Tools/TestWebKitAPI/Tests/WTF/AlignedRefLogger.h (from rev 295007, trunk/Source/_javascript_Core/heap/TinyBloomFilter.h) (0 => 295008)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/AlignedRefLogger.h (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/AlignedRefLogger.h 2022-05-29 03:23:06 UTC (rev 295008)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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. AND ITS CONTRIBUTORS ``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 ITS 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 "Logger.h"
+
+namespace TestWebKitAPI {
+
+struct alignas(16) AlignedRefLogger {
+ AlignedRefLogger(const char* name)
+ : name { *name }
+ {
+ }
+
+ void ref()
+ {
+ log() << "ref(" << &name << ") ";
+ }
+
+ void deref()
+ {
+ log() << "deref(" << &name << ") ";
+ }
+
+ const char& name;
+};
+
+struct DerivedAlignedRefLogger : AlignedRefLogger {
+ DerivedAlignedRefLogger(const char* name)
+ : AlignedRefLogger { name }
+ {
+ }
+};
+
+}
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/CompactPtr.cpp (0 => 295008)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/CompactPtr.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/CompactPtr.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2022 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include <wtf/CompactPtr.h>
+
+#include "AlignedRefLogger.h"
+#include "Utilities.h"
+#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RunLoop.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Threading.h>
+
+namespace TestWebKitAPI {
+
+TEST(WTF_CompactPtr, Basic)
+{
+ DerivedAlignedRefLogger a("a");
+
+ CompactPtr<AlignedRefLogger> empty;
+ EXPECT_EQ(nullptr, empty.get());
+
+ {
+ CompactPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ EXPECT_EQ(&a, &*ptr);
+ EXPECT_EQ(&a.name, &ptr->name);
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr = &a;
+ EXPECT_EQ(&a, ptr.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2(p1);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2 = p1;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2 = WTFMove(p1);
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2(WTFMove(p1));
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+
+ {
+ CompactPtr<DerivedAlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2 = p1;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+
+ {
+ CompactPtr<DerivedAlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2 = WTFMove(p1);
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ ptr = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr(nullptr);
+ EXPECT_EQ(nullptr, ptr.get());
+ EXPECT_EQ(false, static_cast<bool>(ptr));
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ EXPECT_EQ(true, !ptr);
+ }
+
+ {
+ DerivedAlignedRefLogger b("b");
+ DerivedAlignedRefLogger* p1 = &a;
+ CompactPtr<DerivedAlignedRefLogger> p2(&b);
+ p2.swap(p1);
+ EXPECT_EQ(p1, &b);
+ EXPECT_EQ(p2.get(), &a);
+ }
+}
+
+TEST(WTF_CompactPtr, Assignment)
+{
+ DerivedAlignedRefLogger a("a");
+ AlignedRefLogger b("b");
+ DerivedAlignedRefLogger c("c");
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2 = &b;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ p1 = p2;
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ ptr = &b;
+ EXPECT_EQ(&b, ptr.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ ptr = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<AlignedRefLogger> p2 = &b;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ p1 = WTFMove(p2);
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<DerivedAlignedRefLogger> p2 = &c;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ p1 = p2;
+ EXPECT_EQ(&c, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> p1 = &a;
+ CompactPtr<DerivedAlignedRefLogger> p2 = &c;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ p1 = WTFMove(p2);
+ EXPECT_EQ(&c, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ }
+
+ {
+ CompactPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ ptr = &c;
+ EXPECT_EQ(&c, ptr.get());
+ }
+}
+
+} // namespace TestWebKitAPI
Added: trunk/Tools/TestWebKitAPI/Tests/WTF/CompactRefPtr.cpp (0 => 295008)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/CompactRefPtr.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/CompactRefPtr.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2022 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include <wtf/CompactRefPtr.h>
+
+#include "AlignedRefLogger.h"
+#include "Utilities.h"
+#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RunLoop.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Threading.h>
+
+namespace TestWebKitAPI {
+
+TEST(WTF_CompactRefPtr, Basic)
+{
+ DerivedAlignedRefLogger a("a");
+
+ CompactRefPtr<AlignedRefLogger> empty;
+ EXPECT_EQ(nullptr, empty.get());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ EXPECT_EQ(&a, &*ptr);
+ EXPECT_EQ(&a.name, &ptr->name);
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr = &a;
+ EXPECT_EQ(&a, ptr.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2(p1);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2 = p1;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2 = WTFMove(p1);
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2(WTFMove(p1));
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<DerivedAlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2 = p1;
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<DerivedAlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2 = WTFMove(p1);
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ ptr = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(nullptr);
+ EXPECT_EQ(nullptr, ptr.get());
+ EXPECT_EQ(false, static_cast<bool>(ptr));
+ }
+ EXPECT_STREQ("", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ EXPECT_EQ(true, !ptr);
+ }
+ EXPECT_STREQ("", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, AssignPassRefToCompactRefPtr)
+{
+ DerivedAlignedRefLogger a("a");
+ {
+ Ref<AlignedRefLogger> passRef(a);
+ CompactRefPtr<AlignedRefLogger> ptr = WTFMove(passRef);
+ EXPECT_EQ(&a, ptr.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, Adopt)
+{
+ DerivedAlignedRefLogger a("a");
+
+ CompactRefPtr<AlignedRefLogger> empty;
+ EXPECT_EQ(nullptr, empty.get());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(adoptRef(&a));
+ EXPECT_EQ(&a, ptr.get());
+ EXPECT_EQ(&a, &*ptr);
+ EXPECT_EQ(&a.name, &ptr->name);
+ }
+ EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr = adoptRef(&a);
+ EXPECT_EQ(&a, ptr.get());
+ }
+ EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, Assignment)
+{
+ DerivedAlignedRefLogger a("a");
+ AlignedRefLogger b("b");
+ DerivedAlignedRefLogger c("c");
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<AlignedRefLogger> p2(&b);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ p1 = p2;
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | ref(b) deref(a) | deref(b) deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+ ptr = &b;
+ EXPECT_EQ(&b, ptr.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) | ref(b) deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+ ptr = adoptRef(&b);
+ EXPECT_EQ(&b, ptr.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) | deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ ptr = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<AlignedRefLogger> p2(&b);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ p1 = WTFMove(p2);
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<DerivedAlignedRefLogger> p2(&c);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ log() << "| ";
+ p1 = p2;
+ EXPECT_EQ(&c, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(c) | ref(c) deref(a) | deref(c) deref(c) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+ ptr = &c;
+ EXPECT_EQ(&c, ptr.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) | ref(c) deref(a) | deref(c) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+ ptr = adoptRef(&c);
+ EXPECT_EQ(&c, ptr.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) | deref(a) | deref(c) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<DerivedAlignedRefLogger> p2(&c);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ log() << "| ";
+ p1 = WTFMove(p2);
+ EXPECT_EQ(&c, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(c) | deref(a) | deref(c) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wunknown-warning-option"
+#pragma clang diagnostic ignored "-Wself-assign-overloaded"
+#endif
+ ptr = ptr;
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) | ref(a) deref(a) | deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+ ptr = WTFMove(ptr);
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
+ EXPECT_EQ(&a, ptr.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, Swap)
+{
+ AlignedRefLogger a("a");
+ AlignedRefLogger b("b");
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<AlignedRefLogger> p2(&b);
+ log() << "| ";
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ p1.swap(p2);
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | | deref(a) deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<AlignedRefLogger> p2(&b);
+ log() << "| ";
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ std::swap(p1, p2);
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | | deref(a) deref(b) ", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, ReleaseNonNull)
+{
+ AlignedRefLogger a("a");
+
+ {
+ CompactRefPtr<AlignedRefLogger> refPtr = &a;
+ CompactRefPtr<AlignedRefLogger> ref = refPtr.releaseNonNull();
+ }
+
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, Release)
+{
+ DerivedAlignedRefLogger a("a");
+ AlignedRefLogger b("b");
+ DerivedAlignedRefLogger c("c");
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2 = WTFMove(p1);
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2(WTFMove(p1));
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<DerivedAlignedRefLogger> p1 = &a;
+ CompactRefPtr<AlignedRefLogger> p2 = WTFMove(p1);
+ EXPECT_EQ(nullptr, p1.get());
+ EXPECT_EQ(&a, p2.get());
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<AlignedRefLogger> p2(&b);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ p1 = WTFMove(p2);
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<AlignedRefLogger> p1(&a);
+ CompactRefPtr<DerivedAlignedRefLogger> p2(&c);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&c, p2.get());
+ log() << "| ";
+ p1 = WTFMove(p2);
+ EXPECT_EQ(&c, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(c) | deref(a) | deref(c) ", takeLogStr().c_str());
+}
+
+static CompactRefPtr<AlignedRefLogger> f1(AlignedRefLogger& logger)
+{
+ return CompactRefPtr<AlignedRefLogger>(&logger);
+}
+
+TEST(WTF_CompactRefPtr, ReturnValue)
+{
+ DerivedAlignedRefLogger a("a");
+
+ {
+ f1(a);
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ auto ptr = f1(a);
+ }
+ EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+}
+
+struct alignas(16) ConstRefCounted
+ : RefCounted<ConstRefCounted> {
+ static Ref<ConstRefCounted> create() { return adoptRef(*new ConstRefCounted); }
+};
+
+static const ConstRefCounted& returnConstRefCountedRef()
+{
+ static NeverDestroyed<ConstRefCounted> instance;
+ return instance.get();
+}
+static ConstRefCounted& returnRefCountedRef()
+{
+ static NeverDestroyed<ConstRefCounted> instance;
+ return instance.get();
+}
+
+TEST(WTF_CompactRefPtr, Const)
+{
+ // This test passes if it compiles without an error.
+ auto a = ConstRefCounted::create();
+ Ref<const ConstRefCounted> b = WTFMove(a);
+ CompactRefPtr<const ConstRefCounted> c = b.ptr();
+ Ref<const ConstRefCounted> d = returnConstRefCountedRef();
+ CompactRefPtr<const ConstRefCounted> e = &returnConstRefCountedRef();
+ CompactRefPtr<ConstRefCounted> f = ConstRefCounted::create();
+ CompactRefPtr<const ConstRefCounted> g = f;
+ CompactRefPtr<const ConstRefCounted> h(f);
+ Ref<const ConstRefCounted> i(returnRefCountedRef());
+}
+
+struct CompactRefPtrCheckingAlignedRefLogger : AlignedRefLogger {
+ CompactRefPtrCheckingAlignedRefLogger(const char* name);
+ void ref();
+ void deref();
+ const CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger>* slotToCheck { nullptr };
+};
+
+CompactRefPtrCheckingAlignedRefLogger::CompactRefPtrCheckingAlignedRefLogger(const char* name)
+ : AlignedRefLogger { name }
+{
+}
+
+static const char* loggerName(const CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger>& pointer)
+{
+ return pointer ? &pointer->name : "null";
+}
+
+void CompactRefPtrCheckingAlignedRefLogger::ref()
+{
+ if (slotToCheck)
+ log() << "slot=" << loggerName(*slotToCheck) << " ";
+ AlignedRefLogger::ref();
+}
+
+void CompactRefPtrCheckingAlignedRefLogger::deref()
+{
+ if (slotToCheck)
+ log() << "slot=" << loggerName(*slotToCheck) << " ";
+ AlignedRefLogger::deref();
+}
+
+TEST(WTF_CompactRefPtr, AssignBeforeDeref)
+{
+ CompactRefPtrCheckingAlignedRefLogger a("a");
+ CompactRefPtrCheckingAlignedRefLogger b("b");
+
+ {
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> p1(&a);
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> p2(&b);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ a.slotToCheck = &p1;
+ b.slotToCheck = &p1;
+ p1 = p2;
+ a.slotToCheck = nullptr;
+ b.slotToCheck = nullptr;
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | slot=a ref(b) slot=b deref(a) | deref(b) deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ log() << "| ";
+ a.slotToCheck = &ptr;
+ b.slotToCheck = &ptr;
+ ptr = &b;
+ a.slotToCheck = nullptr;
+ b.slotToCheck = nullptr;
+ EXPECT_EQ(&b, ptr.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) | slot=a ref(b) slot=b deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> ptr(&a);
+ EXPECT_EQ(&a, ptr.get());
+ a.slotToCheck = &ptr;
+ ptr = nullptr;
+ a.slotToCheck = nullptr;
+ EXPECT_EQ(nullptr, ptr.get());
+ }
+ EXPECT_STREQ("ref(a) slot=null deref(a) ", takeLogStr().c_str());
+
+ {
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> p1(&a);
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> p2(&b);
+ EXPECT_EQ(&a, p1.get());
+ EXPECT_EQ(&b, p2.get());
+ log() << "| ";
+ a.slotToCheck = &p1;
+ b.slotToCheck = &p1;
+ p1 = WTFMove(p2);
+ a.slotToCheck = nullptr;
+ b.slotToCheck = nullptr;
+ EXPECT_EQ(&b, p1.get());
+ EXPECT_EQ(nullptr, p2.get());
+ log() << "| ";
+ }
+ EXPECT_STREQ("ref(a) ref(b) | slot=b deref(a) | deref(b) ", takeLogStr().c_str());
+}
+
+TEST(WTF_CompactRefPtr, ReleaseNonNullBeforeDeref)
+{
+ CompactRefPtrCheckingAlignedRefLogger a("a");
+
+ {
+ CompactRefPtr<CompactRefPtrCheckingAlignedRefLogger> refPtr = &a;
+ a.slotToCheck = &refPtr;
+ refPtr.releaseNonNull();
+ a.slotToCheck = nullptr;
+ }
+
+ EXPECT_STREQ("ref(a) slot=null deref(a) ", takeLogStr().c_str());
+}
+
+} // namespace TestWebKitAPI
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/JSONValue.cpp (295007 => 295008)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/JSONValue.cpp 2022-05-29 02:03:33 UTC (rev 295007)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/JSONValue.cpp 2022-05-29 03:23:06 UTC (rev 295008)
@@ -700,7 +700,11 @@
Ref<JSON::Value> value = JSON::Value::create(makeString("test"_s));
size_t memoryCost = value->memoryCost();
EXPECT_GT(memoryCost, 0U);
+#if HAVE(36BIT_ADDRESS)
+ EXPECT_LE(memoryCost, 44U);
+#else
EXPECT_LE(memoryCost, 36U);
+#endif
}
{
@@ -707,7 +711,11 @@
Ref<JSON::Value> value = JSON::Value::create(emptyString());
size_t memoryCost = value->memoryCost();
EXPECT_GT(memoryCost, 0U);
+#if HAVE(36BIT_ADDRESS)
+ EXPECT_LE(memoryCost, 40U);
+#else
EXPECT_LE(memoryCost, 32U);
+#endif
}
{