Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (248142 => 248143)
--- trunk/Source/_javascript_Core/ChangeLog 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,3 +1,72 @@
+2019-08-01 Mark Lam <mark....@apple.com>
+
+ Add crash diagnostics for debugging unexpected zapped cells.
+ https://bugs.webkit.org/show_bug.cgi?id=200149
+ <rdar://problem/53570112>
+
+ Reviewed by Yusuke Suzuki.
+
+ Add a check for zapped cells in SlotVisitor::appendToMarkStack() and
+ SlotVisitor::visitChildren(). If a zapped cell is detected, we will crash with
+ some diagnostic info.
+
+ To facilitate this, we've made the following changes:
+ 1. Changed FreeCell to preserve the 1st 8 bytes. This is fine to do because all
+ cells are at least 16 bytes long.
+ 2. Changed HeapCell::zap() to only zap the structureID. Leave the rest of the
+ cell header info intact (including the cell JSType).
+ 3. Changed HeapCell::zap() to record the reason for zapping the cell. We stash
+ the reason immediately after the first 8 bytes. This is the same location as
+ FreeCell::scrambledNext. However, since a cell is not expected to be zapped
+ and on the free list at the same time, it is also fine to do this.
+ 4. Added a few utility functions to MarkedBlock for checking if a cell points
+ into the block.
+ 5. Added VMInspector and JSDollarVM utilities to dump in-use subspace hashes.
+ 6. Added some comments to document the hashes of known subspaces.
+ 7. Added Options::dumpZappedCellCrashData() to make this check conditional.
+ We use this option to disable this check for slower machines so that their
+ PLT5 performance is not impacted.
+
+ * assembler/CPU.cpp:
+ (JSC::hwL3CacheSize):
+ (JSC::hwPhysicalCPUMax):
+ * assembler/CPU.h:
+ (JSC::hwL3CacheSize):
+ (JSC::hwPhysicalCPUMax):
+ * heap/FreeList.h:
+ (JSC::FreeCell::offsetOfScrambledNext):
+ * heap/HeapCell.h:
+ (JSC::HeapCell::zap):
+ (JSC::HeapCell::isZapped const):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::Handle::stopAllocating):
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::Handle::start const):
+ (JSC::MarkedBlock::Handle::end const):
+ (JSC::MarkedBlock::Handle::contains const):
+ * heap/MarkedBlockInlines.h:
+ (JSC::MarkedBlock::Handle::specializedSweep):
+ * heap/MarkedSpace.h:
+ (JSC::MarkedSpace::forEachSubspace):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::appendToMarkStack):
+ (JSC::SlotVisitor::visitChildren):
+ (JSC::SlotVisitor::reportZappedCellAndCrash):
+ * heap/SlotVisitor.h:
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator):
+ * runtime/Options.cpp:
+ (JSC::Options::initialize):
+ * runtime/Options.h:
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * tools/JSDollarVM.cpp:
+ (JSC::functionDumpSubspaceHashes):
+ (JSC::JSDollarVM::finishCreation):
+ * tools/VMInspector.cpp:
+ (JSC::VMInspector::dumpSubspaceHashes):
+ * tools/VMInspector.h:
+
2019-08-01 Keith Miller <keith_mil...@apple.com>
Fix bug in testMulImm32SignExtend
Modified: trunk/Source/_javascript_Core/assembler/CPU.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/assembler/CPU.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/assembler/CPU.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -66,6 +66,27 @@
});
return result;
}
+
+int64_t hwL3CacheSize()
+{
+ int64_t val = 0;
+ size_t valSize = sizeof(val);
+ int rc = sysctlbyname("hw.l3cachesize", &val, &valSize, nullptr, 0);
+ if (rc < 0)
+ return 0;
+ return val;
+}
+
+int32_t hwPhysicalCPUMax()
+{
+ int64_t val = 0;
+ size_t valSize = sizeof(val);
+ int rc = sysctlbyname("hw.physicalcpu_max", &val, &valSize, nullptr, 0);
+ if (rc < 0)
+ return 0;
+ return val;
+}
+
#endif // #if (CPU(X86) || CPU(X86_64)) && OS(DARWIN)
} // namespace JSC
Modified: trunk/Source/_javascript_Core/assembler/CPU.h (248142 => 248143)
--- trunk/Source/_javascript_Core/assembler/CPU.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/assembler/CPU.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -145,10 +145,14 @@
bool isKernTCSMAvailable();
bool enableKernTCSM();
int kernTCSMAwareNumberOfProcessorCores();
+int64_t hwL3CacheSize();
+int32_t hwPhysicalCPUMax();
#else
ALWAYS_INLINE bool isKernTCSMAvailable() { return false; }
ALWAYS_INLINE bool enableKernTCSM() { return false; }
ALWAYS_INLINE int kernTCSMAwareNumberOfProcessorCores() { return WTF::numberOfProcessorCores(); }
+ALWAYS_INLINE int64_t hwL3CacheSize() { return 0; }
+ALWAYS_INLINE int32_t hwPhysicalCPUMax() { return kernTCSMAwareNumberOfProcessorCores(); }
#endif
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/FreeList.h (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/FreeList.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/FreeList.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,6 +53,9 @@
return descramble(scrambledNext, secret);
}
+ static ptrdiff_t offsetOfScrambledNext() { return OBJECT_OFFSETOF(FreeCell, scrambledNext); }
+
+ uint64_t preservedBitsForCrashAnalysis;
uintptr_t scrambledNext;
};
Modified: trunk/Source/_javascript_Core/heap/HeapCell.h (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/HeapCell.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/HeapCell.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,8 +47,17 @@
HeapCell() { }
- void zap() { *reinterpret_cast_ptr<uintptr_t**>(this) = 0; }
- bool isZapped() const { return !*reinterpret_cast_ptr<uintptr_t* const*>(this); }
+ // We're intentionally only zapping the bits for the structureID and leaving
+ // the rest of the cell header bits intact for crash analysis uses.
+ enum ZapReason : int8_t { Unspecified, Destruction, StopAllocating };
+ void zap(ZapReason reason)
+ {
+ uint32_t* cellWords = bitwise_cast<uint32_t*>(this);
+ cellWords[0] = 0;
+ // Leaving cellWords[1] alone for crash analysis if needed.
+ cellWords[2] = reason;
+ }
+ bool isZapped() const { return !*bitwise_cast<const uint32_t*>(this); }
bool isLive();
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -161,7 +161,7 @@
if (MarkedBlockInternal::verbose)
dataLog("Free cell: ", RawPointer(cell), "\n");
if (m_attributes.destruction == NeedsDestruction)
- cell->zap();
+ cell->zap(HeapCell::StopAllocating);
block().clearNewlyAllocated(cell);
});
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -198,6 +198,10 @@
void didAddToDirectory(BlockDirectory*, size_t index);
void didRemoveFromDirectory();
+ void* start() const { return &m_block->atoms()[0]; }
+ void* end() const { return &m_block->atoms()[m_endAtom]; }
+ bool contains(void* p) const { return start() <= p && p < end(); }
+
void dumpState(PrintStream&);
private:
Modified: trunk/Source/_javascript_Core/heap/MarkedBlockInlines.h (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/MarkedBlockInlines.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/MarkedBlockInlines.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -258,7 +258,7 @@
JSCell* jsCell = static_cast<JSCell*>(cell);
if (!jsCell->isZapped()) {
destroyFunc(vm, jsCell);
- jsCell->zap();
+ jsCell->zap(HeapCell::Destruction);
}
};
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.h (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -124,6 +124,7 @@
template<typename Functor> void forEachLiveCell(HeapIterationScope&, const Functor&);
template<typename Functor> void forEachDeadCell(HeapIterationScope&, const Functor&);
template<typename Functor> void forEachBlock(const Functor&);
+ template<typename Functor> void forEachSubspace(const Functor&);
void shrink();
void freeBlock(MarkedBlock::Handle*);
@@ -240,6 +241,16 @@
}
}
+template<typename Functor>
+void MarkedSpace::forEachSubspace(const Functor& functor)
+{
+ for (auto subspace : m_subspaces) {
+ if (functor(*subspace) == IterationStatus::Done)
+ return;
+ }
+}
+
+
ALWAYS_INLINE size_t MarkedSpace::optimalSizeFor(size_t bytes)
{
ASSERT(bytes);
Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/SlotVisitor.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -286,8 +286,14 @@
ALWAYS_INLINE void SlotVisitor::appendToMarkStack(ContainerType& container, JSCell* cell)
{
ASSERT(m_heap.isMarked(cell));
+#if CPU(X86_64)
+ if (Options::dumpZappedCellCrashData()) {
+ if (UNLIKELY(cell->isZapped()))
+ reportZappedCellAndCrash(cell);
+ }
+#endif
ASSERT(!cell->isZapped());
-
+
container.noteMarked();
m_visitCount++;
@@ -385,6 +391,17 @@
default:
// FIXME: This could be so much better.
// https://bugs.webkit.org/show_bug.cgi?id=162462
+#if CPU(X86_64)
+ if (Options::dumpZappedCellCrashData()) {
+ Structure* structure = cell->structure(vm());
+ if (LIKELY(structure)) {
+ const MethodTable* methodTable = &structure->classInfo()->methodTable;
+ methodTable->visitChildren(const_cast<JSCell*>(cell), *this);
+ break;
+ }
+ reportZappedCellAndCrash(const_cast<JSCell*>(cell));
+ }
+#endif
cell->methodTable(vm())->visitChildren(const_cast<JSCell*>(cell), *this);
break;
}
@@ -804,4 +821,33 @@
m_currentSolver->addParallelTask(task, *m_currentConstraint);
}
+#if CPU(X86_64)
+NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void SlotVisitor::reportZappedCellAndCrash(JSCell* cell)
+{
+ MarkedBlock::Handle* foundBlock = nullptr;
+ uint32_t* cellWords = reinterpret_cast_ptr<uint32_t*>(this);
+
+ uintptr_t cellAddress = bitwise_cast<uintptr_t>(cell);
+ uintptr_t headerWord = cellWords[1];
+ uintptr_t zapReason = cellWords[2];
+ unsigned subspaceHash = 0;
+ size_t cellSize = 0;
+
+ m_heap.objectSpace().forEachBlock([&] (MarkedBlock::Handle* block) {
+ if (block->contains(cell)) {
+ foundBlock = block;
+ return IterationStatus::Done;
+ }
+ return IterationStatus::Continue;
+ });
+
+ if (foundBlock) {
+ subspaceHash = StringHasher::computeHash(foundBlock->subspace()->name());
+ cellSize = foundBlock->cellSize();
+ }
+
+ CRASH_WITH_INFO(cellAddress, headerWord, zapReason, subspaceHash, cellSize);
+}
+#endif // PLATFORM(MAC)
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (248142 => 248143)
--- trunk/Source/_javascript_Core/heap/SlotVisitor.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -227,6 +227,10 @@
bool hasWork(const AbstractLocker&);
bool didReachTermination(const AbstractLocker&);
+#if CPU(X86_64)
+ NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void reportZappedCellAndCrash(JSCell*);
+#endif
+
template<typename Func>
IterationStatus forEachMarkStack(const Func&);
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -546,7 +546,7 @@
// The object is half-allocated: we have what we know is a fresh object, but
// it's still on the GC's free list.
- loadPtr(Address(resultGPR), scratchGPR);
+ loadPtr(Address(resultGPR, FreeCell::offsetOfScrambledNext()), scratchGPR);
storePtr(scratchGPR, Address(allocatorGPR, LocalAllocator::offsetOfFreeList() + FreeList::offsetOfScrambledHead()));
done.link(this);
Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/runtime/Options.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -604,6 +604,11 @@
}
}
#endif
+
+#if CPU(X86_64) && OS(DARWIN)
+ Options::dumpZappedCellCrashData() =
+ (hwPhysicalCPUMax() >= 4) && (hwL3CacheSize() >= static_cast<int64_t>(6 * MB));
+#endif
});
}
Modified: trunk/Source/_javascript_Core/runtime/Options.h (248142 => 248143)
--- trunk/Source/_javascript_Core/runtime/Options.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -241,6 +241,7 @@
v(bool, useBumpAllocator, true, Normal, nullptr) \
v(bool, stealEmptyBlocksFromOtherAllocators, true, Normal, nullptr) \
v(bool, eagerlyUpdateTopCallFrame, false, Normal, nullptr) \
+ v(bool, dumpZappedCellCrashData, false, Normal, nullptr) \
\
v(bool, useOSREntryToDFG, true, Normal, nullptr) \
v(bool, useOSREntryToFTL, true, Normal, nullptr) \
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -265,29 +265,29 @@
, webAssemblyCodeBlockHeapCellType(std::make_unique<JSWebAssemblyCodeBlockHeapCellType>())
, webAssemblyFunctionHeapCellType(std::make_unique<WebAssemblyFunctionHeapCellType>())
#endif
- , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), primitiveGigacageAllocator.get())
- , jsValueGigacageAuxiliarySpace("JSValue Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), jsValueGigacageAllocator.get())
- , immutableButterflyJSValueGigacageAuxiliarySpace("ImmutableButterfly Gigacage JSCellWithInteriorPointers", heap, immutableButterflyHeapCellType.get(), jsValueGigacageAllocator.get())
- , cellSpace("JSCell", heap, cellHeapCellType.get(), fastMallocAllocator.get())
- , jsValueGigacageCellSpace("JSValue Gigacage JSCell", heap, cellHeapCellType.get(), jsValueGigacageAllocator.get())
- , destructibleCellSpace("Destructible JSCell", heap, destructibleCellHeapCellType.get(), fastMallocAllocator.get())
- , stringSpace("JSString", heap, stringHeapCellType.get(), fastMallocAllocator.get())
- , destructibleObjectSpace("JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get())
- , eagerlySweptDestructibleObjectSpace("Eagerly Swept JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get())
- , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), ExecutableToCodeBlockEdge)
- , functionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSFunction)
- , internalFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), InternalFunction)
- , nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable)
- , propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable)
- , structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData)
- , structureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), Structure)
- , symbolTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), SymbolTable)
+ , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), primitiveGigacageAllocator.get()) // Hash:0x3e7cd762
+ , jsValueGigacageAuxiliarySpace("JSValue Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), jsValueGigacageAllocator.get()) // Hash:0x241e946
+ , immutableButterflyJSValueGigacageAuxiliarySpace("ImmutableButterfly Gigacage JSCellWithInteriorPointers", heap, immutableButterflyHeapCellType.get(), jsValueGigacageAllocator.get()) // Hash:0x7a945300
+ , cellSpace("JSCell", heap, cellHeapCellType.get(), fastMallocAllocator.get()) // Hash:0xadfb5a79
+ , jsValueGigacageCellSpace("JSValue Gigacage JSCell", heap, cellHeapCellType.get(), jsValueGigacageAllocator.get()) // Hash:0x2f5b102b
+ , destructibleCellSpace("Destructible JSCell", heap, destructibleCellHeapCellType.get(), fastMallocAllocator.get()) // Hash:0xbfff3d73
+ , stringSpace("JSString", heap, stringHeapCellType.get(), fastMallocAllocator.get()) // Hash:0x90cf758f
+ , destructibleObjectSpace("JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get()) // Hash:0x4f5ed7a9
+ , eagerlySweptDestructibleObjectSpace("Eagerly Swept JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get()) // Hash:0x6ebf28e2
+ , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), ExecutableToCodeBlockEdge) // Hash:0x7b730b20
+ , functionSpace ISO_SUBSPACE_INIT(heap, cellHeapCellType.get(), JSFunction) // Hash:0x800fca72
+ , internalFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), InternalFunction) // Hash:0xf845c464
+ , nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable) // Hash:0x67567f95
+ , propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable) // Hash:0xc6bc9f12
+ , structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData) // Hash:0xaca4e62d
+ , structureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), Structure) // Hash:0x1f1bcdca
+ , symbolTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), SymbolTable) // Hash:0xc5215afd
, executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace)
, executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace)
- , codeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), CodeBlock)
- , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable)
- , programExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramExecutable)
- , unlinkedFunctionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), UnlinkedFunctionExecutable)
+ , codeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), CodeBlock) // Hash:0x77e66ec9
+ , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable) // Hash:0x5d158f3
+ , programExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramExecutable) // Hash:0x527c77e7
+ , unlinkedFunctionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), UnlinkedFunctionExecutable) // Hash:0xf6b828d9
, vmType(vmType)
, clientData(0)
, topEntryFrame(nullptr)
@@ -1243,22 +1243,22 @@
}
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(boundFunctionSpace, cellHeapCellType.get(), JSBoundFunction)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(callbackFunctionSpace, destructibleObjectHeapCellType.get(), JSCallbackFunction)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(customGetterSetterFunctionSpace, cellHeapCellType.get(), JSCustomGetterSetterFunction)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(errorInstanceSpace, destructibleObjectHeapCellType.get(), ErrorInstance)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(nativeStdFunctionSpace, cellHeapCellType.get(), JSNativeStdFunction)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(proxyRevokeSpace, destructibleObjectHeapCellType.get(), ProxyRevoke)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakMapSpace, destructibleObjectHeapCellType.get(), JSWeakMap)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakSetSpace, destructibleObjectHeapCellType.get(), JSWeakSet)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakObjectRefSpace, cellHeapCellType.get(), JSWeakObjectRef)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(boundFunctionSpace, cellHeapCellType.get(), JSBoundFunction) // Hash:0xd7916d41
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(callbackFunctionSpace, destructibleObjectHeapCellType.get(), JSCallbackFunction) // Hash:0xe7648ebc
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(customGetterSetterFunctionSpace, cellHeapCellType.get(), JSCustomGetterSetterFunction) // Hash:0x18091000
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(errorInstanceSpace, destructibleObjectHeapCellType.get(), ErrorInstance) // Hash:0x3f40d4a
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(nativeStdFunctionSpace, cellHeapCellType.get(), JSNativeStdFunction) // Hash:0x70ed61e4
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(proxyRevokeSpace, destructibleObjectHeapCellType.get(), ProxyRevoke) // Hash:0xb506a939
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakMapSpace, destructibleObjectHeapCellType.get(), JSWeakMap) // Hash:0x662b12a3
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakSetSpace, destructibleObjectHeapCellType.get(), JSWeakSet) // Hash:0x4c781b30
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(weakObjectRefSpace, cellHeapCellType.get(), JSWeakObjectRef) // Hash:0x8ec68f1f
#if JSC_OBJC_API_ENABLED
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(objCCallbackFunctionSpace, destructibleObjectHeapCellType.get(), ObjCCallbackFunction)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(objCCallbackFunctionSpace, destructibleObjectHeapCellType.get(), ObjCCallbackFunction) // Hash:0x10f610b8
#endif
#if ENABLE(WEBASSEMBLY)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyCodeBlockSpace, webAssemblyCodeBlockHeapCellType.get(), JSWebAssemblyCodeBlock)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyFunctionSpace, webAssemblyFunctionHeapCellType.get(), WebAssemblyFunction)
-DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyWrapperFunctionSpace, cellHeapCellType.get(), WebAssemblyWrapperFunction)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyCodeBlockSpace, webAssemblyCodeBlockHeapCellType.get(), JSWebAssemblyCodeBlock) // Hash:0x9ad995cd
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyFunctionSpace, webAssemblyFunctionHeapCellType.get(), WebAssemblyFunction) // Hash:0x8b7c32db
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyWrapperFunctionSpace, cellHeapCellType.get(), WebAssemblyWrapperFunction) // Hash:0xd4a5ff01
#endif
#undef DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW
@@ -1273,8 +1273,8 @@
return &m_##name->space; \
}
-DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(evalExecutableSpace, destructibleCellHeapCellType.get(), EvalExecutable)
-DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(moduleProgramExecutableSpace, destructibleCellHeapCellType.get(), ModuleProgramExecutable)
+DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(evalExecutableSpace, destructibleCellHeapCellType.get(), EvalExecutable) // Hash:0x958e3e9d
+DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(moduleProgramExecutableSpace, destructibleCellHeapCellType.get(), ModuleProgramExecutable) // Hash:0x6506fa3c
#undef DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW
Modified: trunk/Source/_javascript_Core/tools/JSDollarVM.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/tools/JSDollarVM.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/tools/JSDollarVM.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1394,6 +1394,15 @@
return JSValue::encode(jsUndefined());
}
+// Dumps the hashes of all subspaces currently registered with the VM.
+// Usage: $vm.dumpSubspaceHashes()
+static EncodedJSValue JSC_HOST_CALL functionDumpSubspaceHashes(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ VMInspector::dumpSubspaceHashes(&vm);
+ return JSValue::encode(jsUndefined());
+}
+
// Gets a JSDollarVMCallFrame for a specified frame index.
// Usage: var callFrame = $vm.callFrame(0) // frame 0 is the top frame.
// Usage: var callFrame = $vm.callFrame() // implies frame 0 i.e. current frame.
@@ -2225,6 +2234,7 @@
addFunction(vm, "gc", functionGC, 0);
addFunction(vm, "edenGC", functionEdenGC, 0);
+ addFunction(vm, "dumpSubspaceHashes", functionDumpSubspaceHashes, 0);
addFunction(vm, "callFrame", functionCallFrame, 1);
addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
Modified: trunk/Source/_javascript_Core/tools/VMInspector.cpp (248142 => 248143)
--- trunk/Source/_javascript_Core/tools/VMInspector.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/tools/VMInspector.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -626,4 +626,17 @@
#undef INDENT
}
+void VMInspector::dumpSubspaceHashes(VM* vm)
+{
+ unsigned count = 0;
+ vm->heap.objectSpace().forEachSubspace([&] (const Subspace& subspace) -> IterationStatus {
+ const char* name = subspace.name();
+ unsigned hash = StringHasher::computeHash(name);
+ void* hashAsPtr = reinterpret_cast<void*>(static_cast<uintptr_t>(hash));
+ dataLogLn(" [", count++, "] ", name, " Hash:", RawPointer(hashAsPtr));
+ return IterationStatus::Continue;
+ });
+ dataLogLn();
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/tools/VMInspector.h (248142 => 248143)
--- trunk/Source/_javascript_Core/tools/VMInspector.h 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/_javascript_Core/tools/VMInspector.h 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -78,6 +78,7 @@
JS_EXPORT_PRIVATE static void dumpValue(JSValue);
JS_EXPORT_PRIVATE static void dumpCellMemory(JSCell*);
JS_EXPORT_PRIVATE static void dumpCellMemoryToStream(JSCell*, PrintStream&);
+ JS_EXPORT_PRIVATE static void dumpSubspaceHashes(VM*);
private:
template <typename Functor> void iterate(const Functor& functor)
Modified: trunk/Source/WebCore/ChangeLog (248142 => 248143)
--- trunk/Source/WebCore/ChangeLog 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/WebCore/ChangeLog 2019-08-02 01:58:11 UTC (rev 248143)
@@ -1,3 +1,19 @@
+2019-08-01 Mark Lam <mark....@apple.com>
+
+ Add crash diagnostics for debugging unexpected zapped cells.
+ https://bugs.webkit.org/show_bug.cgi?id=200149
+ <rdar://problem/53570112>
+
+ Reviewed by Yusuke Suzuki.
+
+ No new tests because this is a feature for debugging crashes. It has been tested
+ manually by modifying the code to force a crash at the point of interest.
+
+ Added some comments to document the hashes of known subspaces.
+
+ * bindings/js/WebCoreJSClientData.cpp:
+ (WebCore::JSVMClientData::JSVMClientData):
+
2019-08-01 Saam Barati <sbar...@apple.com>
[WHLSL] Do simple nullptr check elimination using basic data flow analysis when generating metal code
Modified: trunk/Source/WebCore/bindings/js/WebCoreJSClientData.cpp (248142 => 248143)
--- trunk/Source/WebCore/bindings/js/WebCoreJSClientData.cpp 2019-08-02 00:03:46 UTC (rev 248142)
+++ trunk/Source/WebCore/bindings/js/WebCoreJSClientData.cpp 2019-08-02 01:58:11 UTC (rev 248143)
@@ -43,9 +43,9 @@
JSVMClientData::JSVMClientData(VM& vm)
: m_builtinFunctions(vm)
, m_builtinNames(&vm)
- , m_runtimeMethodSpace ISO_SUBSPACE_INIT(vm.heap, vm.destructibleObjectHeapCellType.get(), RuntimeMethod)
- , m_outputConstraintSpace("WebCore Wrapper w/ Output Constraint", vm.heap, vm.destructibleObjectHeapCellType.get(), vm.fastMallocAllocator.get())
- , m_globalObjectOutputConstraintSpace("WebCore Global Object w/ Output Constraint", vm.heap, vm.cellHeapCellType.get(), vm.fastMallocAllocator.get())
+ , m_runtimeMethodSpace ISO_SUBSPACE_INIT(vm.heap, vm.destructibleObjectHeapCellType.get(), RuntimeMethod) // Hash:0xf70c4a85
+ , m_outputConstraintSpace("WebCore Wrapper w/ Output Constraint", vm.heap, vm.destructibleObjectHeapCellType.get(), vm.fastMallocAllocator.get()) // Hash:0x7724c2e4
+ , m_globalObjectOutputConstraintSpace("WebCore Global Object w/ Output Constraint", vm.heap, vm.cellHeapCellType.get(), vm.fastMallocAllocator.get()) // Hash:0x522d6ec9
{
}