Skip to content

Commit 6df1a80

Browse files
Added WTF::StackStats mechanism.
https://bugs.webkit.org/show_bug.cgi?id=99805. Reviewed by Geoffrey Garen. Source/JavaScriptCore: Added StackStats checkpoints and probes. * bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::emitNode): (JSC::BytecodeGenerator::emitNodeInConditionContext): * heap/SlotVisitor.cpp: (JSC::SlotVisitor::append): (JSC::visitChildren): (JSC::SlotVisitor::donateKnownParallel): (JSC::SlotVisitor::drain): (JSC::SlotVisitor::drainFromShared): (JSC::SlotVisitor::mergeOpaqueRoots): (JSC::SlotVisitor::internalAppend): (JSC::SlotVisitor::harvestWeakReferences): (JSC::SlotVisitor::finalizeUnconditionalFinalizers): * interpreter/Interpreter.cpp: (JSC::Interpreter::execute): (JSC::Interpreter::executeCall): (JSC::Interpreter::executeConstruct): (JSC::Interpreter::prepareForRepeatCall): * parser/Parser.h: (JSC::Parser::canRecurse): * runtime/StringRecursionChecker.h: (StringRecursionChecker): Source/WebCore: Added StackStats probes in layout methods. * dom/Document.cpp: (WebCore::Document::updateLayout): * rendering/RenderBlock.cpp: (WebCore::RenderBlock::layout): * rendering/RenderBox.cpp: (WebCore::RenderBox::layout): * rendering/RenderDialog.cpp: (WebCore::RenderDialog::layout): * rendering/RenderEmbeddedObject.cpp: (WebCore::RenderEmbeddedObject::layout): * rendering/RenderFlowThread.cpp: (WebCore::RenderFlowThread::layout): * rendering/RenderFrameSet.cpp: (WebCore::RenderFrameSet::layout): * rendering/RenderIFrame.cpp: (WebCore::RenderIFrame::layout): * rendering/RenderImage.cpp: (WebCore::RenderImage::layout): * rendering/RenderListBox.cpp: (WebCore::RenderListBox::layout): * rendering/RenderListItem.cpp: (WebCore::RenderListItem::layout): * rendering/RenderListMarker.cpp: (WebCore::RenderListMarker::layout): * rendering/RenderMedia.cpp: (WebCore::RenderMedia::layout): * rendering/RenderObject.cpp: (WebCore::RenderObject::layout): * rendering/RenderObject.h: * rendering/RenderRegion.cpp: (WebCore::RenderRegion::layout): * rendering/RenderReplaced.cpp: (WebCore::RenderReplaced::layout): * rendering/RenderReplica.cpp: (WebCore::RenderReplica::layout): * rendering/RenderRubyRun.cpp: (WebCore::RenderRubyRun::layoutSpecialExcludedChild): * rendering/RenderScrollbarPart.cpp: (WebCore::RenderScrollbarPart::layout): * rendering/RenderSlider.cpp: (WebCore::RenderSlider::layout): * rendering/RenderTable.cpp: (WebCore::RenderTable::layout): * rendering/RenderTableCell.cpp: (WebCore::RenderTableCell::layout): * rendering/RenderTableRow.cpp: (WebCore::RenderTableRow::layout): * rendering/RenderTableSection.cpp: (WebCore::RenderTableSection::layout): * rendering/RenderTextControlSingleLine.cpp: (WebCore::RenderTextControlSingleLine::layout): * rendering/RenderTextTrackCue.cpp: (WebCore::RenderTextTrackCue::layout): * rendering/RenderVideo.cpp: (WebCore::RenderVideo::layout): * rendering/RenderView.cpp: (WebCore::RenderView::layout): * rendering/RenderWidget.cpp: (WebCore::RenderWidget::layout): * rendering/svg/RenderSVGContainer.cpp: (WebCore::RenderSVGContainer::layout): * rendering/svg/RenderSVGForeignObject.cpp: (WebCore::RenderSVGForeignObject::layout): * rendering/svg/RenderSVGGradientStop.cpp: (WebCore::RenderSVGGradientStop::layout): * rendering/svg/RenderSVGHiddenContainer.cpp: (WebCore::RenderSVGHiddenContainer::layout): * rendering/svg/RenderSVGImage.cpp: (WebCore::RenderSVGImage::layout): * rendering/svg/RenderSVGResourceContainer.cpp: (WebCore::RenderSVGResourceContainer::layout): * rendering/svg/RenderSVGResourceMarker.cpp: (WebCore::RenderSVGResourceMarker::layout): * rendering/svg/RenderSVGRoot.cpp: (WebCore::RenderSVGRoot::layout): * rendering/svg/RenderSVGShape.cpp: (WebCore::RenderSVGShape::layout): * rendering/svg/RenderSVGText.cpp: (WebCore::RenderSVGText::layout): Source/WTF: Disabled by default. Should have no performance and memory cost when disabled. To enable, #define ENABLE_STACK_STATS 1 in StackStats.h. The output is currently hardcoded to be dumped in /tmp/stack-stats.log, and is in the form of stack sample events. By default, it only logs a sample event when a new high watermark value is encountered. Also renamed StackBounds::recursiveCheck() to isSafeToRecurse(). * WTF.xcodeproj/project.pbxproj: * wtf/StackBounds.h: (StackBounds): (WTF::StackBounds::size): (WTF::StackBounds::isSafeToRecurse): * wtf/StackStats.cpp: Added. (WTF): (WTF::StackStats::initialize): (WTF::StackStats::PerThreadStats::PerThreadStats): (WTF::StackStats::CheckPoint::CheckPoint): (WTF::StackStats::CheckPoint::~CheckPoint): (WTF::StackStats::probe): (WTF::StackStats::LayoutCheckPoint::LayoutCheckPoint): (WTF::StackStats::LayoutCheckPoint::~LayoutCheckPoint): * wtf/StackStats.h: Added. (WTF): (StackStats): (CheckPoint): (WTF::StackStats::CheckPoint::CheckPoint): (PerThreadStats): (WTF::StackStats::PerThreadStats::PerThreadStats): (LayoutCheckPoint): (WTF::StackStats::LayoutCheckPoint::LayoutCheckPoint): (WTF::StackStats::initialize): (WTF::StackStats::probe): * wtf/ThreadingPthreads.cpp: (WTF::initializeThreading): * wtf/WTFThreadData.cpp: (WTF::WTFThreadData::WTFThreadData): * wtf/WTFThreadData.h: (WTFThreadData): (WTF::WTFThreadData::stackStats): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@131938 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 3649748 commit 6df1a80

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+736
-6
lines changed

Source/JavaScriptCore/ChangeLog

+32
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
2012-10-19 Mark Lam <[email protected]>
2+
3+
Added WTF::StackStats mechanism.
4+
https://bugs.webkit.org/show_bug.cgi?id=99805.
5+
6+
Reviewed by Geoffrey Garen.
7+
8+
Added StackStats checkpoints and probes.
9+
10+
* bytecompiler/BytecodeGenerator.h:
11+
(JSC::BytecodeGenerator::emitNode):
12+
(JSC::BytecodeGenerator::emitNodeInConditionContext):
13+
* heap/SlotVisitor.cpp:
14+
(JSC::SlotVisitor::append):
15+
(JSC::visitChildren):
16+
(JSC::SlotVisitor::donateKnownParallel):
17+
(JSC::SlotVisitor::drain):
18+
(JSC::SlotVisitor::drainFromShared):
19+
(JSC::SlotVisitor::mergeOpaqueRoots):
20+
(JSC::SlotVisitor::internalAppend):
21+
(JSC::SlotVisitor::harvestWeakReferences):
22+
(JSC::SlotVisitor::finalizeUnconditionalFinalizers):
23+
* interpreter/Interpreter.cpp:
24+
(JSC::Interpreter::execute):
25+
(JSC::Interpreter::executeCall):
26+
(JSC::Interpreter::executeConstruct):
27+
(JSC::Interpreter::prepareForRepeatCall):
28+
* parser/Parser.h:
29+
(JSC::Parser::canRecurse):
30+
* runtime/StringRecursionChecker.h:
31+
(StringRecursionChecker):
32+
133
2012-10-19 Oliver Hunt <[email protected]>
234

335
REGRESSION(r131822): It made 500+ tests crash on 32 bit platforms

Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ namespace JSC {
311311
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
312312
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
313313
addLineInfo(n->lineNo());
314-
return m_stack.recursionCheck()
314+
return m_stack.isSafeToRecurse()
315315
? n->emitBytecode(*this, dst)
316316
: emitThrowExpressionTooDeepException();
317317
}
@@ -324,7 +324,7 @@ namespace JSC {
324324
void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
325325
{
326326
addLineInfo(n->lineNo());
327-
if (m_stack.recursionCheck())
327+
if (m_stack.isSafeToRecurse())
328328
n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
329329
else
330330
emitThrowExpressionTooDeepException();

Source/JavaScriptCore/heap/SlotVisitor.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "JSGlobalData.h"
1111
#include "JSObject.h"
1212
#include "JSString.h"
13+
#include <wtf/StackStats.h>
1314

1415
namespace JSC {
1516

@@ -58,6 +59,7 @@ void SlotVisitor::reset()
5859

5960
void SlotVisitor::append(ConservativeRoots& conservativeRoots)
6061
{
62+
StackStats::probe();
6163
JSCell** roots = conservativeRoots.roots();
6264
size_t size = conservativeRoots.size();
6365
for (size_t i = 0; i < size; ++i)
@@ -66,6 +68,7 @@ void SlotVisitor::append(ConservativeRoots& conservativeRoots)
6668

6769
ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell)
6870
{
71+
StackStats::probe();
6972
#if ENABLE(SIMPLE_HEAP_PROFILING)
7073
m_visitedTypeCounts.count(cell);
7174
#endif
@@ -92,6 +95,7 @@ ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell
9295

9396
void SlotVisitor::donateKnownParallel()
9497
{
98+
StackStats::probe();
9599
// NOTE: Because we re-try often, we can afford to be conservative, and
96100
// assume that donating is not profitable.
97101

@@ -119,6 +123,7 @@ void SlotVisitor::donateKnownParallel()
119123

120124
void SlotVisitor::drain()
121125
{
126+
StackStats::probe();
122127
ASSERT(m_isInParallelMode);
123128

124129
#if ENABLE(PARALLEL_GC)
@@ -144,6 +149,7 @@ void SlotVisitor::drain()
144149

145150
void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode)
146151
{
152+
StackStats::probe();
147153
ASSERT(m_isInParallelMode);
148154

149155
ASSERT(Options::numberOfGCMarkers());
@@ -221,6 +227,7 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode)
221227

222228
void SlotVisitor::mergeOpaqueRoots()
223229
{
230+
StackStats::probe();
224231
ASSERT(!m_opaqueRoots.isEmpty()); // Should only be called when opaque roots are non-empty.
225232
{
226233
MutexLocker locker(m_shared.m_opaqueRootsLock);
@@ -276,6 +283,7 @@ ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot)
276283
// as it can change the JSValue pointed to be the argument when the original JSValue
277284
// is a string that contains the same contents as another string.
278285

286+
StackStats::probe();
279287
ASSERT(slot);
280288
JSValue value = *slot;
281289
ASSERT(value);
@@ -309,12 +317,14 @@ ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot)
309317

310318
void SlotVisitor::harvestWeakReferences()
311319
{
320+
StackStats::probe();
312321
for (WeakReferenceHarvester* current = m_shared.m_weakReferenceHarvesters.head(); current; current = current->next())
313322
current->visitWeakReferences(*this);
314323
}
315324

316325
void SlotVisitor::finalizeUnconditionalFinalizers()
317326
{
327+
StackStats::probe();
318328
while (m_shared.m_unconditionalFinalizers.hasNext())
319329
m_shared.m_unconditionalFinalizers.removeNext()->finalizeUnconditionally();
320330
}

Source/JavaScriptCore/interpreter/Interpreter.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "StrongInlines.h"
6666
#include <limits.h>
6767
#include <stdio.h>
68+
#include <wtf/StackStats.h>
6869
#include <wtf/Threading.h>
6970
#include <wtf/text/StringBuilder.h>
7071

@@ -752,6 +753,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
752753
if (callFrame->globalData().isCollectorBusy())
753754
CRASH();
754755

756+
StackStats::CheckPoint stackCheckPoint;
755757
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
756758
return checkedReturn(throwStackOverflowError(callFrame));
757759

@@ -914,6 +916,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
914916
if (callFrame->globalData().isCollectorBusy())
915917
return jsNull();
916918

919+
StackStats::CheckPoint stackCheckPoint;
917920
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
918921
return checkedReturn(throwStackOverflowError(callFrame));
919922

@@ -1009,6 +1012,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
10091012
if (callFrame->globalData().isCollectorBusy())
10101013
return checkedReturn(throwStackOverflowError(callFrame));
10111014

1015+
StackStats::CheckPoint stackCheckPoint;
10121016
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
10131017
return checkedReturn(throwStackOverflowError(callFrame));
10141018

@@ -1106,6 +1110,7 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
11061110
if (callFrame->globalData().isCollectorBusy())
11071111
return CallFrameClosure();
11081112

1113+
StackStats::CheckPoint stackCheckPoint;
11091114
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
11101115
throwStackOverflowError(callFrame);
11111116
return CallFrameClosure();
@@ -1147,6 +1152,8 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
11471152
ASSERT(!closure.oldCallFrame->globalData().isCollectorBusy());
11481153
if (closure.oldCallFrame->globalData().isCollectorBusy())
11491154
return jsNull();
1155+
1156+
StackStats::CheckPoint stackCheckPoint;
11501157
closure.resetCallFrame();
11511158
if (Profiler* profiler = closure.oldCallFrame->globalData().enabledProfiler())
11521159
profiler->willExecute(closure.oldCallFrame, closure.function);
@@ -1189,6 +1196,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
11891196

11901197
DynamicGlobalObjectScope globalObjectScope(*scope->globalData(), scope->globalObject());
11911198

1199+
StackStats::CheckPoint stackCheckPoint;
11921200
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
11931201
return checkedReturn(throwStackOverflowError(callFrame));
11941202

Source/JavaScriptCore/parser/Parser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ class Parser {
882882

883883
bool canRecurse()
884884
{
885-
return m_stack.recursionCheck();
885+
return m_stack.isSafeToRecurse();
886886
}
887887

888888
int lastTokenEnd() const

Source/JavaScriptCore/runtime/StringRecursionChecker.h

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define StringRecursionChecker_h
2222

2323
#include "Interpreter.h"
24+
#include <wtf/StackStats.h>
2425

2526
namespace JSC {
2627

@@ -41,6 +42,8 @@ class StringRecursionChecker {
4142
ExecState* m_exec;
4243
JSObject* m_thisObject;
4344
JSValue m_earlyReturnValue;
45+
46+
StackStats::CheckPoint stackCheckpoint;
4447
};
4548

4649
inline JSValue StringRecursionChecker::performCheck()

Source/WTF/ChangeLog

+48
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,51 @@
1+
2012-10-19 Mark Lam <[email protected]>
2+
3+
Added WTF::StackStats mechanism.
4+
https://bugs.webkit.org/show_bug.cgi?id=99805.
5+
6+
Reviewed by Geoffrey Garen.
7+
8+
Disabled by default. Should have no performance and memory cost when
9+
disabled. To enable, #define ENABLE_STACK_STATS 1 in StackStats.h.
10+
The output is currently hardcoded to be dumped in /tmp/stack-stats.log,
11+
and is in the form of stack sample events. By default, it only logs
12+
a sample event when a new high watermark value is encountered.
13+
14+
Also renamed StackBounds::recursiveCheck() to isSafeToRecurse().
15+
16+
* WTF.xcodeproj/project.pbxproj:
17+
* wtf/StackBounds.h:
18+
(StackBounds):
19+
(WTF::StackBounds::size):
20+
(WTF::StackBounds::isSafeToRecurse):
21+
* wtf/StackStats.cpp: Added.
22+
(WTF):
23+
(WTF::StackStats::initialize):
24+
(WTF::StackStats::PerThreadStats::PerThreadStats):
25+
(WTF::StackStats::CheckPoint::CheckPoint):
26+
(WTF::StackStats::CheckPoint::~CheckPoint):
27+
(WTF::StackStats::probe):
28+
(WTF::StackStats::LayoutCheckPoint::LayoutCheckPoint):
29+
(WTF::StackStats::LayoutCheckPoint::~LayoutCheckPoint):
30+
* wtf/StackStats.h: Added.
31+
(WTF):
32+
(StackStats):
33+
(CheckPoint):
34+
(WTF::StackStats::CheckPoint::CheckPoint):
35+
(PerThreadStats):
36+
(WTF::StackStats::PerThreadStats::PerThreadStats):
37+
(LayoutCheckPoint):
38+
(WTF::StackStats::LayoutCheckPoint::LayoutCheckPoint):
39+
(WTF::StackStats::initialize):
40+
(WTF::StackStats::probe):
41+
* wtf/ThreadingPthreads.cpp:
42+
(WTF::initializeThreading):
43+
* wtf/WTFThreadData.cpp:
44+
(WTF::WTFThreadData::WTFThreadData):
45+
* wtf/WTFThreadData.h:
46+
(WTFThreadData):
47+
(WTF::WTFThreadData::stackStats):
48+
149
2012-10-19 Anders Carlsson <[email protected]>
250

351
Deque can use std::reverse_iterator for its reverse iterators

Source/WTF/WTF.xcodeproj/project.pbxproj

+8
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@
296296
F3525E461619A4EE00278BC1 /* MemoryInstrumentationHashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = F3525E451619A4EE00278BC1 /* MemoryInstrumentationHashMap.h */; };
297297
F3FBC71E161AF7BF00BB4BD4 /* MemoryInstrumentationHashCountedSet.h in Headers */ = {isa = PBXBuildFile; fileRef = F3FBC71D161AF7BF00BB4BD4 /* MemoryInstrumentationHashCountedSet.h */; };
298298
F3FBC720161AF7CD00BB4BD4 /* MemoryInstrumentationSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = F3FBC71F161AF7CD00BB4BD4 /* MemoryInstrumentationSequence.h */; };
299+
FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; };
300+
FEDACD3E1630F83F00C69634 /* StackStats.h in Headers */ = {isa = PBXBuildFile; fileRef = FEDACD3C1630F83F00C69634 /* StackStats.h */; };
299301
/* End PBXBuildFile section */
300302

301303
/* Begin PBXContainerItemProxy section */
@@ -594,6 +596,8 @@
594596
F3525E451619A4EE00278BC1 /* MemoryInstrumentationHashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryInstrumentationHashMap.h; sourceTree = "<group>"; };
595597
F3FBC71D161AF7BF00BB4BD4 /* MemoryInstrumentationHashCountedSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryInstrumentationHashCountedSet.h; sourceTree = "<group>"; };
596598
F3FBC71F161AF7CD00BB4BD4 /* MemoryInstrumentationSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryInstrumentationSequence.h; sourceTree = "<group>"; };
599+
FEDACD3B1630F83F00C69634 /* StackStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackStats.cpp; sourceTree = "<group>"; };
600+
FEDACD3C1630F83F00C69634 /* StackStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackStats.h; sourceTree = "<group>"; };
597601
/* End PBXFileReference section */
598602

599603
/* Begin PBXFrameworksBuildPhase section */
@@ -804,6 +808,8 @@
804808
A8A4730D151A825B004123FF /* Spectrum.h */,
805809
A8A4730E151A825B004123FF /* StackBounds.cpp */,
806810
A8A4730F151A825B004123FF /* StackBounds.h */,
811+
FEDACD3B1630F83F00C69634 /* StackStats.cpp */,
812+
FEDACD3C1630F83F00C69634 /* StackStats.h */,
807813
A8A47310151A825B004123FF /* StaticConstructors.h */,
808814
A8A47311151A825B004123FF /* StdLibExtras.h */,
809815
1A6BB768162F300500DD16DB /* StreamBuffer.h */,
@@ -1150,6 +1156,7 @@
11501156
A8A47424151A825B004123FF /* SinglyLinkedList.h in Headers */,
11511157
A8A47426151A825B004123FF /* Spectrum.h in Headers */,
11521158
A8A47428151A825B004123FF /* StackBounds.h in Headers */,
1159+
FEDACD3E1630F83F00C69634 /* StackStats.h in Headers */,
11531160
A8A47429151A825B004123FF /* StaticConstructors.h in Headers */,
11541161
A8A4742A151A825B004123FF /* StdLibExtras.h in Headers */,
11551162
1A6BB769162F300500DD16DB /* StreamBuffer.h in Headers */,
@@ -1341,6 +1348,7 @@
13411348
A8A47421151A825B004123FF /* SHA1.cpp in Sources */,
13421349
A8A47425151A825B004123FF /* SizeLimits.cpp in Sources */,
13431350
A8A47427151A825B004123FF /* StackBounds.cpp in Sources */,
1351+
FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */,
13441352
A8A4743C151A825B004123FF /* StringBuilder.cpp in Sources */,
13451353
A8A4742B151A825B004123FF /* StringExtras.cpp in Sources */,
13461354
A8A47440151A825B004123FF /* StringImpl.cpp in Sources */,

Source/WTF/wtf/StackBounds.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,15 @@
3030
namespace WTF {
3131

3232
class StackBounds {
33-
// recursionCheck() / recursionLimit() tests (by default)
33+
// isSafeToRecurse() / recursionLimit() tests (by default)
3434
// that we are at least this far from the end of the stack.
35-
const static size_t s_defaultAvailabilityDelta = 4096;
35+
//
36+
// This 64k number was picked because a sampling of stack usage differences
37+
// between consecutive entries into one of the Interpreter::execute...()
38+
// functions was seen to be as high as 27k. Hence, 64k is chosen as a
39+
// conservative availability value that is not too large but comfortably
40+
// exceeds 27k with some buffer for error.
41+
const static size_t s_defaultAvailabilityDelta = 64 * 1024;
3642

3743
public:
3844
StackBounds()
@@ -62,6 +68,13 @@ class StackBounds {
6268
return currentPosition;
6369
}
6470

71+
size_t size() const
72+
{
73+
return isGrowingDownward()
74+
? static_cast<char*>(m_origin) - static_cast<char*>(m_bound)
75+
: static_cast<char*>(m_bound) - static_cast<char*>(m_origin);
76+
}
77+
6578
void* recursionLimit(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
6679
{
6780
checkConsistency();
@@ -70,7 +83,7 @@ class StackBounds {
7083
: static_cast<char*>(m_bound) - minAvailableDelta;
7184
}
7285

73-
bool recursionCheck(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
86+
bool isSafeToRecurse(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
7487
{
7588
checkConsistency();
7689
return isGrowingDownward()
@@ -105,6 +118,8 @@ class StackBounds {
105118

106119
void* m_origin;
107120
void* m_bound;
121+
122+
friend class StackStats;
108123
};
109124

110125
} // namespace WTF

0 commit comments

Comments
 (0)