Commit add88110 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by V8 LUCI CQ

[compiler] improve escape analysis for receivers and closures

When a receiver/closure is not used by a lazy deopt frame state, then
it cannot escape through the .getThis API. Therefore, it's safe to
dematerialize it.

Bug: chromium:1315901, chromium:1318126
Change-Id: I5cf9c30e8451a7af94d371162a94eb1ba0c9db4a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3726299Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81415}
parent 44cd69a7
......@@ -170,6 +170,7 @@ class EscapeAnalysisTracker : public ZoneObject {
Zone* zone)
: virtual_objects_(zone),
replacements_(zone),
framestate_might_lazy_deopt_(zone),
variable_states_(jsgraph, reducer, zone),
jsgraph_(jsgraph),
zone_(zone) {}
......@@ -246,6 +247,31 @@ class EscapeAnalysisTracker : public ZoneObject {
void MarkForDeletion() { SetReplacement(tracker_->jsgraph_->Dead()); }
bool FrameStateMightLazyDeopt(Node* framestate) {
DCHECK_EQ(IrOpcode::kFrameState, framestate->opcode());
if (auto it = tracker_->framestate_might_lazy_deopt_.find(framestate);
it != tracker_->framestate_might_lazy_deopt_.end()) {
return it->second;
}
for (Node* use : framestate->uses()) {
switch (use->opcode()) {
case IrOpcode::kCheckpoint:
case IrOpcode::kDeoptimize:
case IrOpcode::kDeoptimizeIf:
case IrOpcode::kDeoptimizeUnless:
// These nodes only cause eager deopts.
break;
default:
if (use->opcode() == IrOpcode::kFrameState &&
!FrameStateMightLazyDeopt(use)) {
break;
}
return tracker_->framestate_might_lazy_deopt_[framestate] = true;
}
}
return tracker_->framestate_might_lazy_deopt_[framestate] = false;
}
~Scope() {
if (replacement_ != tracker_->replacements_[current_node()] ||
vobject_ != tracker_->virtual_objects_.Get(current_node())) {
......@@ -282,6 +308,7 @@ class EscapeAnalysisTracker : public ZoneObject {
SparseSidetable<VirtualObject*> virtual_objects_;
Sidetable<Node*> replacements_;
ZoneUnorderedMap<Node*, bool> framestate_might_lazy_deopt_;
VariableTracker variable_states_;
VirtualObject::Id next_object_id_ = 0;
JSGraph* const jsgraph_;
......@@ -820,6 +847,10 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current,
type != FrameStateType::kJavaScriptBuiltinContinuationWithCatch) {
break;
}
if (!current->FrameStateMightLazyDeopt(current->CurrentNode())) {
// Only lazy deopt frame states are used to generate stack traces.
break;
}
StateValuesAccess::iterator it =
StateValuesAccess(frame_state.parameters()).begin();
if (!it.done()) {
......
......@@ -1801,9 +1801,8 @@ void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames) const {
FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
}
// Prepare iteration over translation. Note that the below iteration might
// materialize objects without storing them back to the Isolate, this will
// lead to objects being re-materialized again for each summary.
// Prepare iteration over translation. We must not materialize values here
// because we do not deoptimize the function.
TranslatedState translated(this);
translated.Prepare(fp());
......@@ -1821,12 +1820,14 @@ void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames) const {
// at the first position, and the receiver is next.
TranslatedFrame::iterator translated_values = it->begin();
// Get or materialize the correct function in the optimized frame.
// Get the correct function in the optimized frame.
CHECK(!translated_values->IsMaterializedObject());
Handle<JSFunction> function =
Handle<JSFunction>::cast(translated_values->GetValue());
translated_values++;
// Get or materialize the correct receiver in the optimized frame.
// Get the correct receiver in the optimized frame.
CHECK(!translated_values->IsMaterializedObject());
Handle<Object> receiver = translated_values->GetValue();
translated_values++;
......
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