Skip to content

Commit cedc81d

Browse files
ripsawridgeCommit Bot
authored andcommitted
[Sampling Heap Profiler] Tolerate unmaterialized closure during deopt
Samples taken during deoptimization require care in the stack walk used to gather frames. The top N stack frames may not have JSFunction objects in place, because those frames represent inlined functions which may not have closures yet. Bug: v8:7314 Change-Id: Ib6488aee46a47d5341cab1b1c9c3851592ba6509 Reviewed-on: https://chromium-review.googlesource.com/870036 Commit-Queue: Ali Ijaz Sheikh <[email protected]> Reviewed-by: Michael Starzinger <[email protected]> Reviewed-by: Ali Ijaz Sheikh <[email protected]> Cr-Commit-Position: refs/heads/master@{#50732}
1 parent 50a91fe commit cedc81d

3 files changed

Lines changed: 20 additions & 4 deletions

File tree

src/frames.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,15 @@ JSFunction* JavaScriptFrame::function() const {
10231023
return JSFunction::cast(function_slot_object());
10241024
}
10251025

1026+
Object* JavaScriptFrame::unchecked_function() const {
1027+
// During deoptimization of an optimized function, we may have yet to
1028+
// materialize some closures on the stack. The arguments marker object
1029+
// marks this case.
1030+
DCHECK(function_slot_object()->IsJSFunction() ||
1031+
isolate()->heap()->arguments_marker() == function_slot_object());
1032+
return function_slot_object();
1033+
}
1034+
10261035
Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
10271036

10281037
Object* JavaScriptFrame::context() const {

src/frames.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ class JavaScriptFrame : public StandardFrame {
704704

705705
// Accessors.
706706
virtual JSFunction* function() const;
707+
Object* unchecked_function() const;
707708
Object* receiver() const override;
708709
Object* context() const override;
709710
Script* script() const override;

src/profiler/sampling-heap-profiler.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,16 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() {
150150
int frames_captured = 0;
151151
while (!it.done() && frames_captured < stack_depth_) {
152152
JavaScriptFrame* frame = it.frame();
153-
SharedFunctionInfo* shared = frame->function()->shared();
154-
stack.push_back(shared);
155-
156-
frames_captured++;
153+
// If we are materializing objects during deoptimization, inlined
154+
// closures may not yet be materialized, and this includes the
155+
// closure on the stack. Skip over any such frames (they'll be
156+
// in the top frames of the stack). The allocations made in this
157+
// sensitive moment belong to the formerly optimized frame anyway.
158+
if (frame->unchecked_function()->IsJSFunction()) {
159+
SharedFunctionInfo* shared = frame->function()->shared();
160+
stack.push_back(shared);
161+
frames_captured++;
162+
}
157163
it.Advance();
158164
}
159165

0 commit comments

Comments
 (0)