Commit cedc81de authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

[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 <ofrobots@google.com>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarAli Ijaz Sheikh <ofrobots@google.com>
Cr-Commit-Position: refs/heads/master@{#50732}
parent 50a91fe9
......@@ -1023,6 +1023,15 @@ JSFunction* JavaScriptFrame::function() const {
return JSFunction::cast(function_slot_object());
}
Object* JavaScriptFrame::unchecked_function() const {
// During deoptimization of an optimized function, we may have yet to
// materialize some closures on the stack. The arguments marker object
// marks this case.
DCHECK(function_slot_object()->IsJSFunction() ||
isolate()->heap()->arguments_marker() == function_slot_object());
return function_slot_object();
}
Object* JavaScriptFrame::receiver() const { return GetParameter(-1); }
Object* JavaScriptFrame::context() const {
......
......@@ -704,6 +704,7 @@ class JavaScriptFrame : public StandardFrame {
// Accessors.
virtual JSFunction* function() const;
Object* unchecked_function() const;
Object* receiver() const override;
Object* context() const override;
Script* script() const override;
......
......@@ -150,10 +150,16 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() {
int frames_captured = 0;
while (!it.done() && frames_captured < stack_depth_) {
JavaScriptFrame* frame = it.frame();
// If we are materializing objects during deoptimization, inlined
// closures may not yet be materialized, and this includes the
// closure on the stack. Skip over any such frames (they'll be
// in the top frames of the stack). The allocations made in this
// sensitive moment belong to the formerly optimized frame anyway.
if (frame->unchecked_function()->IsJSFunction()) {
SharedFunctionInfo* shared = frame->function()->shared();
stack.push_back(shared);
frames_captured++;
}
it.Advance();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment