[compiler] mark receiver and function as escaping

Bug: chromium:1315901
Change-Id: Ic44bfcae32aba202ba25c5f59fe579214a444584
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584117
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79968}
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
index bf693c7..fe8126f 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -5,10 +5,12 @@
 #include "src/compiler/escape-analysis.h"
 
 #include "src/codegen/tick-counter.h"
+#include "src/compiler/frame-states.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/operator-properties.h"
 #include "src/compiler/simplified-operator.h"
+#include "src/compiler/state-values-utils.h"
 #include "src/handles/handles-inl.h"
 #include "src/init/bootstrapper.h"
 #include "src/objects/map-inl.h"
@@ -224,6 +226,11 @@
       return tracker_->ResolveReplacement(
           NodeProperties::GetContextInput(current_node()));
     }
+    // Accessing the current node is fine for `FrameState nodes.
+    Node* CurrentNode() {
+      DCHECK_EQ(current_node()->opcode(), IrOpcode::kFrameState);
+      return current_node();
+    }
 
     void SetReplacement(Node* replacement) {
       replacement_ = replacement;
@@ -799,9 +806,25 @@
       break;
     }
     case IrOpcode::kStateValues:
-    case IrOpcode::kFrameState:
       // These uses are always safe.
       break;
+    case IrOpcode::kFrameState: {
+      // We mark the receiver as escaping due to the non-standard `.getThis`
+      // API.
+      FrameState frame_state{current->CurrentNode()};
+      if (frame_state.frame_state_info().type() !=
+          FrameStateType::kUnoptimizedFunction)
+        break;
+      StateValuesAccess::iterator it =
+          StateValuesAccess(frame_state.parameters()).begin();
+      if (!it.done()) {
+        if (Node* receiver = it.node()) {
+          current->SetEscaped(receiver);
+        }
+        current->SetEscaped(frame_state.function());
+      }
+      break;
+    }
     default: {
       // For unknown nodes, treat all value inputs as escaping.
       int value_input_count = op->ValueInputCount();