Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (258385 => 258386)
--- trunk/Source/_javascript_Core/ChangeLog 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-03-13 07:53:28 UTC (rev 258386)
@@ -1,3 +1,27 @@
+2020-03-12 Yusuke Suzuki <ysuz...@apple.com>
+
+ Report crashed cell in jsCast in debug builds
+ https://bugs.webkit.org/show_bug.cgi?id=209041
+ <rdar://problem/59705631>
+
+ Reviewed by Mark Lam.
+
+ To collect more information when crashing with jsCast, we attempt to use reportZappedCellAndCrash.
+ If it succeeds, we can get more information in registers. We enable this only for ASSERT_ENABLED
+ build. For non ASSERT_ENABLED, we keep the original assertion since this assertion can be enabled
+ via ENABLE(SECURITY_ASSERTIONS).
+
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::appendToMarkStack):
+ (JSC::SlotVisitor::visitChildren):
+ (JSC::SlotVisitor::reportZappedCellAndCrash): Deleted.
+ * heap/SlotVisitor.h:
+ * runtime/JSCast.h:
+ (JSC::jsCast):
+ * runtime/JSCell.cpp:
+ (JSC::reportZappedCellAndCrash):
+ * runtime/JSCell.h:
+
2020-03-12 Keith Miller <keith_mil...@apple.com>
DFG nodes that take a TypedArray's storage need to keepAlive the TypedArray
Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.cpp (258385 => 258386)
--- trunk/Source/_javascript_Core/heap/SlotVisitor.cpp 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.cpp 2020-03-13 07:53:28 UTC (rev 258386)
@@ -294,7 +294,7 @@
#if CPU(X86_64)
if (UNLIKELY(Options::dumpZappedCellCrashData())) {
if (UNLIKELY(cell->isZapped()))
- reportZappedCellAndCrash(cell);
+ reportZappedCellAndCrash(m_heap, cell);
}
#endif
ASSERT(!cell->isZapped());
@@ -404,7 +404,7 @@
methodTable->visitChildren(const_cast<JSCell*>(cell), *this);
break;
}
- reportZappedCellAndCrash(const_cast<JSCell*>(cell));
+ reportZappedCellAndCrash(m_heap, const_cast<JSCell*>(cell));
}
#endif
cell->methodTable(vm())->visitChildren(const_cast<JSCell*>(cell), *this);
@@ -825,46 +825,4 @@
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* foundBlockHandle = nullptr;
- uint64_t* cellWords = reinterpret_cast_ptr<uint64_t*>(cell);
-
- uintptr_t cellAddress = bitwise_cast<uintptr_t>(cell);
- uint64_t headerWord = cellWords[0];
- uint64_t zapReasonAndMore = cellWords[1];
- unsigned subspaceHash = 0;
- size_t cellSize = 0;
-
- m_heap.objectSpace().forEachBlock([&] (MarkedBlock::Handle* blockHandle) {
- if (blockHandle->contains(cell)) {
- foundBlockHandle = blockHandle;
- return IterationStatus::Done;
- }
- return IterationStatus::Continue;
- });
-
- uint64_t variousState = 0;
- MarkedBlock* foundBlock = nullptr;
- if (foundBlockHandle) {
- foundBlock = &foundBlockHandle->block();
- subspaceHash = StringHasher::computeHash(foundBlockHandle->subspace()->name());
- cellSize = foundBlockHandle->cellSize();
-
- variousState |= static_cast<uint64_t>(foundBlockHandle->isFreeListed()) << 0;
- variousState |= static_cast<uint64_t>(foundBlockHandle->isAllocated()) << 1;
- variousState |= static_cast<uint64_t>(foundBlockHandle->isEmpty()) << 2;
- variousState |= static_cast<uint64_t>(foundBlockHandle->needsDestruction()) << 3;
- variousState |= static_cast<uint64_t>(foundBlock->isNewlyAllocated(cell)) << 4;
-
- ptrdiff_t cellOffset = cellAddress - reinterpret_cast<uint64_t>(foundBlockHandle->start());
- bool cellIsProperlyAligned = !(cellOffset % cellSize);
- variousState |= static_cast<uint64_t>(cellIsProperlyAligned) << 5;
- }
-
- CRASH_WITH_INFO(cellAddress, headerWord, zapReasonAndMore, subspaceHash, cellSize, foundBlock, variousState);
-}
-#endif // PLATFORM(MAC)
-
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (258385 => 258386)
--- trunk/Source/_javascript_Core/heap/SlotVisitor.h 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h 2020-03-13 07:53:28 UTC (rev 258386)
@@ -227,10 +227,6 @@
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/runtime/JSCast.h (258385 => 258386)
--- trunk/Source/_javascript_Core/runtime/JSCast.h 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/runtime/JSCast.h 2020-03-13 07:53:28 UTC (rev 258386)
@@ -33,7 +33,12 @@
inline To jsCast(From* from)
{
static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value && std::is_base_of<JSCell, typename std::remove_pointer<From>::type>::value, "JS casting expects that the types you are casting to/from are subclasses of JSCell");
+#if (ASSERT_ENABLED || ENABLE(SECURITY_ASSERTIONS)) && CPU(X86_64)
+ if (from && !from->JSCell::inherits(from->JSCell::vm(), std::remove_pointer<To>::type::info()))
+ reportZappedCellAndCrash(*from->JSCell::heap(), from);
+#else
ASSERT_WITH_SECURITY_IMPLICATION(!from || from->JSCell::inherits(from->JSCell::vm(), std::remove_pointer<To>::type::info()));
+#endif
return static_cast<To>(from);
}
@@ -41,7 +46,14 @@
inline To jsCast(JSValue from)
{
static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value, "JS casting expects that the types you are casting to is a subclass of JSCell");
+#if (ASSERT_ENABLED || ENABLE(SECURITY_ASSERTIONS)) && CPU(X86_64)
+ ASSERT(from.isCell());
+ JSCell* cell = from.asCell();
+ if (!cell->JSCell::inherits(cell->vm(), std::remove_pointer<To>::type::info()))
+ reportZappedCellAndCrash(*cell->JSCell::heap(), cell);
+#else
ASSERT_WITH_SECURITY_IMPLICATION(from.isCell() && from.asCell()->JSCell::inherits(from.asCell()->vm(), std::remove_pointer<To>::type::info()));
+#endif
return static_cast<To>(from.asCell());
}
Modified: trunk/Source/_javascript_Core/runtime/JSCell.cpp (258385 => 258386)
--- trunk/Source/_javascript_Core/runtime/JSCell.cpp 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/runtime/JSCell.cpp 2020-03-13 07:53:28 UTC (rev 258386)
@@ -24,11 +24,13 @@
#include "JSCell.h"
#include "ArrayBufferView.h"
+#include "BlockDirectoryInlines.h"
#include "JSCInlines.h"
#include "JSCast.h"
#include "JSFunction.h"
#include "JSString.h"
#include "JSObject.h"
+#include "MarkedBlockInlines.h"
#include "NumberObject.h"
#include <wtf/LockAlgorithmInlines.h>
#include <wtf/MathExtras.h>
@@ -316,4 +318,46 @@
IndexingTypeLockAlgorithm::unlockSlow(*lock);
}
+#if CPU(X86_64)
+NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void reportZappedCellAndCrash(Heap& heap, const JSCell* cell)
+{
+ MarkedBlock::Handle* foundBlockHandle = nullptr;
+ uint64_t* cellWords = bitwise_cast<uint64_t*>(cell);
+
+ uintptr_t cellAddress = bitwise_cast<uintptr_t>(cell);
+ uint64_t headerWord = cellWords[0];
+ uint64_t zapReasonAndMore = cellWords[1];
+ unsigned subspaceHash = 0;
+ size_t cellSize = 0;
+
+ heap.objectSpace().forEachBlock([&] (MarkedBlock::Handle* blockHandle) {
+ if (blockHandle->contains(bitwise_cast<JSCell*>(cell))) {
+ foundBlockHandle = blockHandle;
+ return IterationStatus::Done;
+ }
+ return IterationStatus::Continue;
+ });
+
+ uint64_t variousState = 0;
+ MarkedBlock* foundBlock = nullptr;
+ if (foundBlockHandle) {
+ foundBlock = &foundBlockHandle->block();
+ subspaceHash = StringHasher::computeHash(foundBlockHandle->subspace()->name());
+ cellSize = foundBlockHandle->cellSize();
+
+ variousState |= static_cast<uint64_t>(foundBlockHandle->isFreeListed()) << 0;
+ variousState |= static_cast<uint64_t>(foundBlockHandle->isAllocated()) << 1;
+ variousState |= static_cast<uint64_t>(foundBlockHandle->isEmpty()) << 2;
+ variousState |= static_cast<uint64_t>(foundBlockHandle->needsDestruction()) << 3;
+ variousState |= static_cast<uint64_t>(foundBlock->isNewlyAllocated(cell)) << 4;
+
+ ptrdiff_t cellOffset = cellAddress - reinterpret_cast<uint64_t>(foundBlockHandle->start());
+ bool cellIsProperlyAligned = !(cellOffset % cellSize);
+ variousState |= static_cast<uint64_t>(cellIsProperlyAligned) << 5;
+ }
+
+ CRASH_WITH_INFO(cellAddress, headerWord, zapReasonAndMore, subspaceHash, cellSize, foundBlock, variousState);
+}
+#endif // CPU(X86_64)
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (258385 => 258386)
--- trunk/Source/_javascript_Core/runtime/JSCell.h 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h 2020-03-13 07:53:28 UTC (rev 258386)
@@ -307,4 +307,8 @@
return Type::template subspaceFor<Type, SubspaceAccess::Concurrently>(vm);
}
+#if CPU(X86_64)
+JS_EXPORT_PRIVATE NEVER_INLINE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void reportZappedCellAndCrash(Heap&, const JSCell*);
+#endif
+
} // namespace JSC
Modified: trunk/Source/WebCore/ChangeLog (258385 => 258386)
--- trunk/Source/WebCore/ChangeLog 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/WebCore/ChangeLog 2020-03-13 07:53:28 UTC (rev 258386)
@@ -1,3 +1,18 @@
+2020-03-12 Yusuke Suzuki <ysuz...@apple.com>
+
+ Report crashed cell in jsCast in debug builds
+ https://bugs.webkit.org/show_bug.cgi?id=209041
+ <rdar://problem/59705631>
+
+ Reviewed by Mark Lam.
+
+ We should take JSLock when touching JSC::VM.
+
+ * page/MemoryRelease.cpp:
+ (WebCore::logMemoryStatisticsAtTimeOfDeath):
+ * page/PerformanceLogging.cpp:
+ (WebCore::PerformanceLogging::memoryUsageStatistics):
+
2020-03-12 Cathie Chen <cathiec...@igalia.com>
REGRESSION(r255957): Element with scroll-behavior:smooth isn't draggable after r255957
Modified: trunk/Source/WebCore/page/MemoryRelease.cpp (258385 => 258386)
--- trunk/Source/WebCore/page/MemoryRelease.cpp 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/WebCore/page/MemoryRelease.cpp 2020-03-13 07:53:28 UTC (rev 258386)
@@ -192,6 +192,7 @@
#endif
auto& vm = commonVM();
+ JSC::JSLockHolder locker(vm);
RELEASE_LOG(MemoryPressure, "Memory usage statistics at time of death:");
RELEASE_LOG(MemoryPressure, "GC heap size: %zu", vm.heap.size());
RELEASE_LOG(MemoryPressure, "GC heap extra memory size: %zu", vm.heap.extraMemorySize());
Modified: trunk/Source/WebCore/page/PerformanceLogging.cpp (258385 => 258386)
--- trunk/Source/WebCore/page/PerformanceLogging.cpp 2020-03-13 07:24:36 UTC (rev 258385)
+++ trunk/Source/WebCore/page/PerformanceLogging.cpp 2020-03-13 07:53:28 UTC (rev 258386)
@@ -56,6 +56,7 @@
HashMap<const char*, size_t> stats;
auto& vm = commonVM();
+ JSC::JSLockHolder locker(vm);
stats.add("_javascript__gc_heap_capacity", vm.heap.capacity());
stats.add("_javascript__gc_heap_extra_memory_size", vm.heap.extraMemorySize());