Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (223023 => 223024)
--- trunk/Source/_javascript_Core/ChangeLog 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-10-08 01:10:19 UTC (rev 223024)
@@ -1,3 +1,32 @@
+2017-10-07 Filip Pizlo <[email protected]>
+
+ Octane/splay can leak memory due to stray pointers on the stack when run from the command line
+ https://bugs.webkit.org/show_bug.cgi?id=178054
+
+ Reviewed by Saam Barati.
+
+ This throws in a bunch of sanitize calls. It fixes the problem. It's also performance-neutral. In
+ most cases, calling the sanitize function is O(1), because it doesn't have anything to do if the stack
+ height stays relatively constant.
+
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGTierUpCheckInjectionPhase.cpp:
+ (JSC::DFG::TierUpCheckInjectionPhase::run):
+ * ftl/FTLOSREntry.cpp:
+ * heap/Heap.cpp:
+ (JSC::Heap::runCurrentPhase):
+ * heap/MarkedAllocatorInlines.h:
+ (JSC::MarkedAllocator::tryAllocate):
+ (JSC::MarkedAllocator::allocate):
+ * heap/Subspace.cpp:
+ (JSC::Subspace::tryAllocateSlow):
+ * jit/AssemblyHelpers.h:
+ (JSC::AssemblyHelpers::sanitizeStackInline):
+ * jit/ThunkGenerators.cpp:
+ (JSC::slowPathFor):
+ * runtime/VM.h:
+ (JSC::VM::addressOfLastStackTop):
+
2017-10-07 Yusuke Suzuki <[email protected]>
`async` should be able to be used as an imported binding name
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -2540,6 +2540,8 @@
// really be profitable.
DeferGCForAWhile deferGC(codeBlock->vm()->heap);
+ sanitizeStackForVM(codeBlock->vm());
+
if (Options::verboseOSR())
dataLog(*codeBlock, ": Entered reoptimize\n");
// We must be called with the baseline code block.
@@ -2665,6 +2667,8 @@
DeferGCForAWhile deferGC(vm->heap);
CodeBlock* codeBlock = exec->codeBlock();
+ sanitizeStackForVM(vm);
+
if (codeBlock->jitType() != JITCode::DFGJIT) {
dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
RELEASE_ASSERT_NOT_REACHED();
@@ -2719,7 +2723,7 @@
// The following is only true for triggerTierUpNowInLoop, which can never
// be an OSR entry.
bool canOSRFromHere = originBytecodeIndex == osrEntryBytecodeIndex;
-
+
bool triggeredSlowPathToStartCompilation = false;
auto tierUpEntryTriggers = jitCode->tierUpEntryTriggers.find(originBytecodeIndex);
if (tierUpEntryTriggers != jitCode->tierUpEntryTriggers.end()) {
@@ -2899,6 +2903,8 @@
DeferGCForAWhile deferGC(vm->heap);
CodeBlock* codeBlock = exec->codeBlock();
+ sanitizeStackForVM(vm);
+
if (codeBlock->jitType() != JITCode::DFGJIT) {
dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
RELEASE_ASSERT_NOT_REACHED();
@@ -2933,6 +2939,8 @@
DeferGCForAWhile deferGC(vm->heap);
CodeBlock* codeBlock = exec->codeBlock();
+ sanitizeStackForVM(vm);
+
if (codeBlock->jitType() != JITCode::DFGJIT) {
dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
RELEASE_ASSERT_NOT_REACHED();
Modified: trunk/Source/_javascript_Core/dfg/DFGTierUpCheckInjectionPhase.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/dfg/DFGTierUpCheckInjectionPhase.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/dfg/DFGTierUpCheckInjectionPhase.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -74,7 +74,7 @@
if (!ensureGlobalFTLWhitelist().contains(m_graph.m_profiledBlock))
return false;
-
+
#if ENABLE(FTL_JIT)
FTL::CapabilityLevel level = FTL::canCompile(m_graph);
if (level == FTL::CannotCompile)
Modified: trunk/Source/_javascript_Core/ftl/FTLOSREntry.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/ftl/FTLOSREntry.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/ftl/FTLOSREntry.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-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
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -1092,6 +1092,9 @@
checkConn(conn);
m_currentThreadState = currentThreadState;
+ if (conn == GCConductor::Mutator)
+ sanitizeStackForVM(vm());
+
// If the collector transfers the conn to the mutator, it leaves us in between phases.
if (!finishChangingPhase(conn)) {
// A mischevious mutator could repeatedly relinquish the conn back to us. We try to avoid doing
Modified: trunk/Source/_javascript_Core/heap/MarkedAllocatorInlines.h (223023 => 223024)
--- trunk/Source/_javascript_Core/heap/MarkedAllocatorInlines.h 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocatorInlines.h 2017-10-08 01:10:19 UTC (rev 223024)
@@ -39,6 +39,7 @@
{
return m_freeList.allocate(
[&] () -> HeapCell* {
+ sanitizeStackForVM(heap()->vm());
return static_cast<HeapCell*>(tryAllocateSlowCase(deferralContext));
});
}
@@ -47,6 +48,7 @@
{
return m_freeList.allocate(
[&] () -> HeapCell* {
+ sanitizeStackForVM(heap()->vm());
return static_cast<HeapCell*>(allocateSlowCase(deferralContext));
});
}
Modified: trunk/Source/_javascript_Core/heap/Subspace.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/heap/Subspace.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/heap/Subspace.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -207,6 +207,8 @@
void* Subspace::tryAllocateSlow(GCDeferralContext* deferralContext, size_t size)
{
+ sanitizeStackForVM(m_space.heap()->vm());
+
if (MarkedAllocator* allocator = allocatorFor(size))
return allocator->tryAllocate(deferralContext);
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -898,6 +898,19 @@
#endif
}
+void AssemblyHelpers::sanitizeStackInline(VM& vm, GPRReg scratch)
+{
+ loadPtr(vm.addressOfLastStackTop(), scratch);
+ Jump done = branchPtr(BelowOrEqual, stackPointerRegister, scratch);
+ Label loop = label();
+ storePtr(TrustedImmPtr(0), scratch);
+ addPtr(TrustedImmPtr(sizeof(void*)), scratch);
+ branchPtr(Above, stackPointerRegister, scratch).linkTo(loop, this);
+ done.link(this);
+ move(stackPointerRegister, scratch);
+ storePtr(scratch, vm.addressOfLastStackTop());
+}
+
} // namespace JSC
#endif // ENABLE(JIT)
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (223023 => 223024)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h 2017-10-08 01:10:19 UTC (rev 223024)
@@ -1387,6 +1387,8 @@
return branchTest8(Zero, AbsoluteAddress(vm.heap.addressOfMutatorShouldBeFenced()));
}
+ void sanitizeStackInline(VM&, GPRReg scratch);
+
// Emits the branch structure for typeof. The code emitted by this doesn't fall through. The
// functor is called at those points where we have pinpointed a type. One way to use this is to
// have the functor emit the code to put the type string into an appropriate register and then
Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (223023 => 223024)
--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp 2017-10-08 01:10:19 UTC (rev 223024)
@@ -81,6 +81,7 @@
static void slowPathFor(
CCallHelpers& jit, VM* vm, Sprt_JITOperation_ECli slowPathFunction)
{
+ jit.sanitizeStackInline(*vm, GPRInfo::nonArgGPR0);
jit.emitFunctionPrologue();
jit.storePtr(GPRInfo::callFrameRegister, &vm->topCallFrame);
#if OS(WINDOWS) && CPU(X86_64)
Modified: trunk/Source/_javascript_Core/runtime/VM.h (223023 => 223024)
--- trunk/Source/_javascript_Core/runtime/VM.h 2017-10-07 23:44:45 UTC (rev 223023)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2017-10-08 01:10:19 UTC (rev 223024)
@@ -553,6 +553,7 @@
return isSafeToRecurse(m_stackLimit);
}
+ void** addressOfLastStackTop() { return &m_lastStackTop; }
void* lastStackTop() { return m_lastStackTop; }
void setLastStackTop(void*);