11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/execution/frames.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <memory>
81cb0ef41Sopenharmony_ci#include <sstream>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/base/bits.h"
111cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h"
141cb0ef41Sopenharmony_ci#include "src/codegen/register-configuration.h"
151cb0ef41Sopenharmony_ci#include "src/codegen/safepoint-table.h"
161cb0ef41Sopenharmony_ci#include "src/common/globals.h"
171cb0ef41Sopenharmony_ci#include "src/deoptimizer/deoptimizer.h"
181cb0ef41Sopenharmony_ci#include "src/execution/frames-inl.h"
191cb0ef41Sopenharmony_ci#include "src/execution/vm-state-inl.h"
201cb0ef41Sopenharmony_ci#include "src/ic/ic-stats.h"
211cb0ef41Sopenharmony_ci#include "src/logging/counters.h"
221cb0ef41Sopenharmony_ci#include "src/objects/code.h"
231cb0ef41Sopenharmony_ci#include "src/objects/slots.h"
241cb0ef41Sopenharmony_ci#include "src/objects/smi.h"
251cb0ef41Sopenharmony_ci#include "src/objects/visitors.h"
261cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/embedded-data-inl.h"
271cb0ef41Sopenharmony_ci#include "src/strings/string-stream.h"
281cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
311cb0ef41Sopenharmony_ci#include "src/debug/debug-wasm-objects.h"
321cb0ef41Sopenharmony_ci#include "src/wasm/wasm-code-manager.h"
331cb0ef41Sopenharmony_ci#include "src/wasm/wasm-engine.h"
341cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects-inl.h"
351cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cinamespace v8 {
381cb0ef41Sopenharmony_cinamespace internal {
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciReturnAddressLocationResolver StackFrame::return_address_location_resolver_ =
411cb0ef41Sopenharmony_ci    nullptr;
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_cinamespace {
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciAddress AddressOf(const StackHandler* handler) {
461cb0ef41Sopenharmony_ci  Address raw = handler->address();
471cb0ef41Sopenharmony_ci#ifdef V8_USE_ADDRESS_SANITIZER
481cb0ef41Sopenharmony_ci  // ASan puts C++-allocated StackHandler markers onto its fake stack.
491cb0ef41Sopenharmony_ci  // We work around that by storing the real stack address in the "padding"
501cb0ef41Sopenharmony_ci  // field. StackHandlers allocated from generated code have 0 as padding.
511cb0ef41Sopenharmony_ci  Address padding =
521cb0ef41Sopenharmony_ci      base::Memory<Address>(raw + StackHandlerConstants::kPaddingOffset);
531cb0ef41Sopenharmony_ci  if (padding != 0) return padding;
541cb0ef41Sopenharmony_ci#endif
551cb0ef41Sopenharmony_ci  return raw;
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci}  // namespace
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci// Iterator that supports traversing the stack handlers of a
611cb0ef41Sopenharmony_ci// particular frame. Needs to know the top of the handler chain.
621cb0ef41Sopenharmony_ciclass StackHandlerIterator {
631cb0ef41Sopenharmony_ci public:
641cb0ef41Sopenharmony_ci  StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
651cb0ef41Sopenharmony_ci      : limit_(frame->fp()), handler_(handler) {
661cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
671cb0ef41Sopenharmony_ci    // Make sure the handler has already been unwound to this frame. With stack
681cb0ef41Sopenharmony_ci    // switching this is not equivalent to the inequality below, because the
691cb0ef41Sopenharmony_ci    // frame and the handler could be in different stacks.
701cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(!FLAG_experimental_wasm_stack_switching,
711cb0ef41Sopenharmony_ci                   frame->sp() <= AddressOf(handler));
721cb0ef41Sopenharmony_ci    // For CWasmEntry frames, the handler was registered by the last C++
731cb0ef41Sopenharmony_ci    // frame (Execution::CallWasm), so even though its address is already
741cb0ef41Sopenharmony_ci    // beyond the limit, we know we always want to unwind one handler.
751cb0ef41Sopenharmony_ci    if (frame->is_c_wasm_entry()) handler_ = handler_->next();
761cb0ef41Sopenharmony_ci#else
771cb0ef41Sopenharmony_ci    // Make sure the handler has already been unwound to this frame.
781cb0ef41Sopenharmony_ci    DCHECK_LE(frame->sp(), AddressOf(handler));
791cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
801cb0ef41Sopenharmony_ci  }
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  StackHandler* handler() const { return handler_; }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  bool done() { return handler_ == nullptr || AddressOf(handler_) > limit_; }
851cb0ef41Sopenharmony_ci  void Advance() {
861cb0ef41Sopenharmony_ci    DCHECK(!done());
871cb0ef41Sopenharmony_ci    handler_ = handler_->next();
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci private:
911cb0ef41Sopenharmony_ci  const Address limit_;
921cb0ef41Sopenharmony_ci  StackHandler* handler_;
931cb0ef41Sopenharmony_ci};
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci#define INITIALIZE_SINGLETON(type, field) field##_(this),
981cb0ef41Sopenharmony_ciStackFrameIteratorBase::StackFrameIteratorBase(Isolate* isolate,
991cb0ef41Sopenharmony_ci                                               bool can_access_heap_objects)
1001cb0ef41Sopenharmony_ci    : isolate_(isolate),
1011cb0ef41Sopenharmony_ci      STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) frame_(nullptr),
1021cb0ef41Sopenharmony_ci      handler_(nullptr),
1031cb0ef41Sopenharmony_ci      can_access_heap_objects_(can_access_heap_objects) {}
1041cb0ef41Sopenharmony_ci#undef INITIALIZE_SINGLETON
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ciStackFrameIterator::StackFrameIterator(Isolate* isolate)
1071cb0ef41Sopenharmony_ci    : StackFrameIterator(isolate, isolate->thread_local_top()) {}
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ciStackFrameIterator::StackFrameIterator(Isolate* isolate, ThreadLocalTop* t)
1101cb0ef41Sopenharmony_ci    : StackFrameIteratorBase(isolate, true) {
1111cb0ef41Sopenharmony_ci  Reset(t);
1121cb0ef41Sopenharmony_ci}
1131cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1141cb0ef41Sopenharmony_ciStackFrameIterator::StackFrameIterator(Isolate* isolate,
1151cb0ef41Sopenharmony_ci                                       wasm::StackMemory* stack)
1161cb0ef41Sopenharmony_ci    : StackFrameIteratorBase(isolate, true) {
1171cb0ef41Sopenharmony_ci  Reset(isolate->thread_local_top(), stack);
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci#endif
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_civoid StackFrameIterator::Advance() {
1221cb0ef41Sopenharmony_ci  DCHECK(!done());
1231cb0ef41Sopenharmony_ci  // Compute the state of the calling frame before restoring
1241cb0ef41Sopenharmony_ci  // callee-saved registers and unwinding handlers. This allows the
1251cb0ef41Sopenharmony_ci  // frame code that computes the caller state to access the top
1261cb0ef41Sopenharmony_ci  // handler and the value of any callee-saved register if needed.
1271cb0ef41Sopenharmony_ci  StackFrame::State state;
1281cb0ef41Sopenharmony_ci  StackFrame::Type type = frame_->GetCallerState(&state);
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  // Unwind handlers corresponding to the current frame.
1311cb0ef41Sopenharmony_ci  StackHandlerIterator it(frame_, handler_);
1321cb0ef41Sopenharmony_ci  while (!it.done()) it.Advance();
1331cb0ef41Sopenharmony_ci  handler_ = it.handler();
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  // Advance to the calling frame.
1361cb0ef41Sopenharmony_ci  frame_ = SingletonFor(type, &state);
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  // When we're done iterating over the stack frames, the handler
1391cb0ef41Sopenharmony_ci  // chain must have been completely unwound. Except for wasm stack-switching:
1401cb0ef41Sopenharmony_ci  // we stop at the end of the current segment.
1411cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1421cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(done() && !FLAG_experimental_wasm_stack_switching,
1431cb0ef41Sopenharmony_ci                 handler_ == nullptr);
1441cb0ef41Sopenharmony_ci#else
1451cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(done(), handler_ == nullptr);
1461cb0ef41Sopenharmony_ci#endif
1471cb0ef41Sopenharmony_ci}
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ciStackFrame* StackFrameIterator::Reframe() {
1501cb0ef41Sopenharmony_ci  StackFrame::Type type = frame_->ComputeType(this, &frame_->state_);
1511cb0ef41Sopenharmony_ci  frame_ = SingletonFor(type, &frame_->state_);
1521cb0ef41Sopenharmony_ci  return frame();
1531cb0ef41Sopenharmony_ci}
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_civoid StackFrameIterator::Reset(ThreadLocalTop* top) {
1561cb0ef41Sopenharmony_ci  StackFrame::State state;
1571cb0ef41Sopenharmony_ci  StackFrame::Type type =
1581cb0ef41Sopenharmony_ci      ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
1591cb0ef41Sopenharmony_ci  handler_ = StackHandler::FromAddress(Isolate::handler(top));
1601cb0ef41Sopenharmony_ci  frame_ = SingletonFor(type, &state);
1611cb0ef41Sopenharmony_ci}
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1641cb0ef41Sopenharmony_civoid StackFrameIterator::Reset(ThreadLocalTop* top, wasm::StackMemory* stack) {
1651cb0ef41Sopenharmony_ci  if (stack->jmpbuf()->sp == kNullAddress) {
1661cb0ef41Sopenharmony_ci    // A null SP indicates that the computation associated with this stack has
1671cb0ef41Sopenharmony_ci    // returned, leaving the stack segment empty.
1681cb0ef41Sopenharmony_ci    return;
1691cb0ef41Sopenharmony_ci  }
1701cb0ef41Sopenharmony_ci  StackFrame::State state;
1711cb0ef41Sopenharmony_ci  StackSwitchFrame::GetStateForJumpBuffer(stack->jmpbuf(), &state);
1721cb0ef41Sopenharmony_ci  handler_ = StackHandler::FromAddress(Isolate::handler(top));
1731cb0ef41Sopenharmony_ci  frame_ = SingletonFor(StackFrame::STACK_SWITCH, &state);
1741cb0ef41Sopenharmony_ci}
1751cb0ef41Sopenharmony_ci#endif
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ciStackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type,
1781cb0ef41Sopenharmony_ci                                                 StackFrame::State* state) {
1791cb0ef41Sopenharmony_ci  StackFrame* result = SingletonFor(type);
1801cb0ef41Sopenharmony_ci  DCHECK((!result) == (type == StackFrame::NO_FRAME_TYPE));
1811cb0ef41Sopenharmony_ci  if (result) result->state_ = *state;
1821cb0ef41Sopenharmony_ci  return result;
1831cb0ef41Sopenharmony_ci}
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ciStackFrame* StackFrameIteratorBase::SingletonFor(StackFrame::Type type) {
1861cb0ef41Sopenharmony_ci#define FRAME_TYPE_CASE(type, field) \
1871cb0ef41Sopenharmony_ci  case StackFrame::type:             \
1881cb0ef41Sopenharmony_ci    return &field##_;
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  switch (type) {
1911cb0ef41Sopenharmony_ci    case StackFrame::NO_FRAME_TYPE:
1921cb0ef41Sopenharmony_ci      return nullptr;
1931cb0ef41Sopenharmony_ci      STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
1941cb0ef41Sopenharmony_ci    default:
1951cb0ef41Sopenharmony_ci      break;
1961cb0ef41Sopenharmony_ci  }
1971cb0ef41Sopenharmony_ci  return nullptr;
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci#undef FRAME_TYPE_CASE
2001cb0ef41Sopenharmony_ci}
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_civoid TypedFrameWithJSLinkage::Iterate(RootVisitor* v) const {
2051cb0ef41Sopenharmony_ci  IterateExpressions(v);
2061cb0ef41Sopenharmony_ci  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
2071cb0ef41Sopenharmony_ci}
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_civoid JavaScriptFrameIterator::Advance() {
2121cb0ef41Sopenharmony_ci  do {
2131cb0ef41Sopenharmony_ci    iterator_.Advance();
2141cb0ef41Sopenharmony_ci  } while (!iterator_.done() && !iterator_.frame()->is_java_script());
2151cb0ef41Sopenharmony_ci}
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ciStackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate)
2201cb0ef41Sopenharmony_ci    : iterator_(isolate) {
2211cb0ef41Sopenharmony_ci  if (!done() && !IsValidFrame(iterator_.frame())) Advance();
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ciStackTraceFrameIterator::StackTraceFrameIterator(Isolate* isolate,
2251cb0ef41Sopenharmony_ci                                                 StackFrameId id)
2261cb0ef41Sopenharmony_ci    : StackTraceFrameIterator(isolate) {
2271cb0ef41Sopenharmony_ci  while (!done() && frame()->id() != id) Advance();
2281cb0ef41Sopenharmony_ci}
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_civoid StackTraceFrameIterator::Advance() {
2311cb0ef41Sopenharmony_ci  do {
2321cb0ef41Sopenharmony_ci    iterator_.Advance();
2331cb0ef41Sopenharmony_ci  } while (!done() && !IsValidFrame(iterator_.frame()));
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ciint StackTraceFrameIterator::FrameFunctionCount() const {
2371cb0ef41Sopenharmony_ci  DCHECK(!done());
2381cb0ef41Sopenharmony_ci  if (!iterator_.frame()->is_optimized()) return 1;
2391cb0ef41Sopenharmony_ci  std::vector<SharedFunctionInfo> infos;
2401cb0ef41Sopenharmony_ci  OptimizedFrame::cast(iterator_.frame())->GetFunctions(&infos);
2411cb0ef41Sopenharmony_ci  return static_cast<int>(infos.size());
2421cb0ef41Sopenharmony_ci}
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ciFrameSummary StackTraceFrameIterator::GetTopValidFrame() const {
2451cb0ef41Sopenharmony_ci  DCHECK(!done());
2461cb0ef41Sopenharmony_ci  // Like FrameSummary::GetTop, but additionally observes
2471cb0ef41Sopenharmony_ci  // StackTraceFrameIterator filtering semantics.
2481cb0ef41Sopenharmony_ci  std::vector<FrameSummary> frames;
2491cb0ef41Sopenharmony_ci  frame()->Summarize(&frames);
2501cb0ef41Sopenharmony_ci  if (is_javascript()) {
2511cb0ef41Sopenharmony_ci    for (int i = static_cast<int>(frames.size()) - 1; i >= 0; i--) {
2521cb0ef41Sopenharmony_ci      if (!IsValidJSFunction(*frames[i].AsJavaScript().function())) continue;
2531cb0ef41Sopenharmony_ci      return frames[i];
2541cb0ef41Sopenharmony_ci    }
2551cb0ef41Sopenharmony_ci    UNREACHABLE();
2561cb0ef41Sopenharmony_ci  }
2571cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2581cb0ef41Sopenharmony_ci  if (is_wasm()) return frames.back();
2591cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2601cb0ef41Sopenharmony_ci  UNREACHABLE();
2611cb0ef41Sopenharmony_ci}
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci// static
2641cb0ef41Sopenharmony_cibool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) {
2651cb0ef41Sopenharmony_ci  if (frame->is_java_script()) {
2661cb0ef41Sopenharmony_ci    return IsValidJSFunction(static_cast<JavaScriptFrame*>(frame)->function());
2671cb0ef41Sopenharmony_ci  }
2681cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2691cb0ef41Sopenharmony_ci  if (frame->is_wasm()) return true;
2701cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2711cb0ef41Sopenharmony_ci  return false;
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci// static
2751cb0ef41Sopenharmony_cibool StackTraceFrameIterator::IsValidJSFunction(JSFunction f) {
2761cb0ef41Sopenharmony_ci  if (!f.IsJSFunction()) return false;
2771cb0ef41Sopenharmony_ci  return f.shared().IsSubjectToDebugging();
2781cb0ef41Sopenharmony_ci}
2791cb0ef41Sopenharmony_ci
2801cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_cinamespace {
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_cibool IsInterpreterFramePc(Isolate* isolate, Address pc,
2851cb0ef41Sopenharmony_ci                          StackFrame::State* state) {
2861cb0ef41Sopenharmony_ci  Builtin builtin = OffHeapInstructionStream::TryLookupCode(isolate, pc);
2871cb0ef41Sopenharmony_ci  if (builtin != Builtin::kNoBuiltinId &&
2881cb0ef41Sopenharmony_ci      (builtin == Builtin::kInterpreterEntryTrampoline ||
2891cb0ef41Sopenharmony_ci       builtin == Builtin::kInterpreterEnterAtBytecode ||
2901cb0ef41Sopenharmony_ci       builtin == Builtin::kInterpreterEnterAtNextBytecode ||
2911cb0ef41Sopenharmony_ci       builtin == Builtin::kBaselineOrInterpreterEnterAtBytecode ||
2921cb0ef41Sopenharmony_ci       builtin == Builtin::kBaselineOrInterpreterEnterAtNextBytecode)) {
2931cb0ef41Sopenharmony_ci    return true;
2941cb0ef41Sopenharmony_ci  } else if (FLAG_interpreted_frames_native_stack) {
2951cb0ef41Sopenharmony_ci    intptr_t marker = Memory<intptr_t>(
2961cb0ef41Sopenharmony_ci        state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
2971cb0ef41Sopenharmony_ci    MSAN_MEMORY_IS_INITIALIZED(
2981cb0ef41Sopenharmony_ci        state->fp + StandardFrameConstants::kFunctionOffset,
2991cb0ef41Sopenharmony_ci        kSystemPointerSize);
3001cb0ef41Sopenharmony_ci    Object maybe_function = Object(
3011cb0ef41Sopenharmony_ci        Memory<Address>(state->fp + StandardFrameConstants::kFunctionOffset));
3021cb0ef41Sopenharmony_ci    // There's no need to run a full ContainsSlow if we know the frame can't be
3031cb0ef41Sopenharmony_ci    // an InterpretedFrame,  so we do these fast checks first
3041cb0ef41Sopenharmony_ci    if (StackFrame::IsTypeMarker(marker) || maybe_function.IsSmi()) {
3051cb0ef41Sopenharmony_ci      return false;
3061cb0ef41Sopenharmony_ci    } else if (!isolate->heap()->InSpaceSlow(pc, CODE_SPACE)) {
3071cb0ef41Sopenharmony_ci      return false;
3081cb0ef41Sopenharmony_ci    }
3091cb0ef41Sopenharmony_ci    Code interpreter_entry_trampoline =
3101cb0ef41Sopenharmony_ci        isolate->heap()->GcSafeFindCodeForInnerPointer(pc);
3111cb0ef41Sopenharmony_ci    return interpreter_entry_trampoline.is_interpreter_trampoline_builtin();
3121cb0ef41Sopenharmony_ci  } else {
3131cb0ef41Sopenharmony_ci    return false;
3141cb0ef41Sopenharmony_ci  }
3151cb0ef41Sopenharmony_ci}
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci}  // namespace
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_cibool SafeStackFrameIterator::IsNoFrameBytecodeHandlerPc(Isolate* isolate,
3201cb0ef41Sopenharmony_ci                                                        Address pc,
3211cb0ef41Sopenharmony_ci                                                        Address fp) const {
3221cb0ef41Sopenharmony_ci  // Return false for builds with non-embedded bytecode handlers.
3231cb0ef41Sopenharmony_ci  if (Isolate::CurrentEmbeddedBlobCode() == nullptr) return false;
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedData::FromBlob(isolate);
3261cb0ef41Sopenharmony_ci  if (pc < d.InstructionStartOfBytecodeHandlers() ||
3271cb0ef41Sopenharmony_ci      pc >= d.InstructionEndOfBytecodeHandlers()) {
3281cb0ef41Sopenharmony_ci    // Not a bytecode handler pc address.
3291cb0ef41Sopenharmony_ci    return false;
3301cb0ef41Sopenharmony_ci  }
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci  if (!IsValidStackAddress(fp +
3331cb0ef41Sopenharmony_ci                           CommonFrameConstants::kContextOrFrameTypeOffset)) {
3341cb0ef41Sopenharmony_ci    return false;
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  // Check if top stack frame is a bytecode handler stub frame.
3381cb0ef41Sopenharmony_ci  MSAN_MEMORY_IS_INITIALIZED(
3391cb0ef41Sopenharmony_ci      fp + CommonFrameConstants::kContextOrFrameTypeOffset, kSystemPointerSize);
3401cb0ef41Sopenharmony_ci  intptr_t marker =
3411cb0ef41Sopenharmony_ci      Memory<intptr_t>(fp + CommonFrameConstants::kContextOrFrameTypeOffset);
3421cb0ef41Sopenharmony_ci  if (StackFrame::IsTypeMarker(marker) &&
3431cb0ef41Sopenharmony_ci      StackFrame::MarkerToType(marker) == StackFrame::STUB) {
3441cb0ef41Sopenharmony_ci    // Bytecode handler built a frame.
3451cb0ef41Sopenharmony_ci    return false;
3461cb0ef41Sopenharmony_ci  }
3471cb0ef41Sopenharmony_ci  return true;
3481cb0ef41Sopenharmony_ci}
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ciSafeStackFrameIterator::SafeStackFrameIterator(Isolate* isolate, Address pc,
3511cb0ef41Sopenharmony_ci                                               Address fp, Address sp,
3521cb0ef41Sopenharmony_ci                                               Address lr, Address js_entry_sp)
3531cb0ef41Sopenharmony_ci    : StackFrameIteratorBase(isolate, false),
3541cb0ef41Sopenharmony_ci      low_bound_(sp),
3551cb0ef41Sopenharmony_ci      high_bound_(js_entry_sp),
3561cb0ef41Sopenharmony_ci      top_frame_type_(StackFrame::NO_FRAME_TYPE),
3571cb0ef41Sopenharmony_ci      top_context_address_(kNullAddress),
3581cb0ef41Sopenharmony_ci      external_callback_scope_(isolate->external_callback_scope()),
3591cb0ef41Sopenharmony_ci      top_link_register_(lr) {
3601cb0ef41Sopenharmony_ci  StackFrame::State state;
3611cb0ef41Sopenharmony_ci  StackFrame::Type type;
3621cb0ef41Sopenharmony_ci  ThreadLocalTop* top = isolate->thread_local_top();
3631cb0ef41Sopenharmony_ci  bool advance_frame = true;
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci  Address fast_c_fp = isolate->isolate_data()->fast_c_call_caller_fp();
3661cb0ef41Sopenharmony_ci  uint8_t stack_is_iterable = isolate->isolate_data()->stack_is_iterable();
3671cb0ef41Sopenharmony_ci  if (!stack_is_iterable) {
3681cb0ef41Sopenharmony_ci    frame_ = nullptr;
3691cb0ef41Sopenharmony_ci    return;
3701cb0ef41Sopenharmony_ci  }
3711cb0ef41Sopenharmony_ci  // 'Fast C calls' are a special type of C call where we call directly from
3721cb0ef41Sopenharmony_ci  // JS to C without an exit frame inbetween. The CEntryStub is responsible
3731cb0ef41Sopenharmony_ci  // for setting Isolate::c_entry_fp, meaning that it won't be set for fast C
3741cb0ef41Sopenharmony_ci  // calls. To keep the stack iterable, we store the FP and PC of the caller
3751cb0ef41Sopenharmony_ci  // of the fast C call on the isolate. This is guaranteed to be the topmost
3761cb0ef41Sopenharmony_ci  // JS frame, because fast C calls cannot call back into JS. We start
3771cb0ef41Sopenharmony_ci  // iterating the stack from this topmost JS frame.
3781cb0ef41Sopenharmony_ci  if (fast_c_fp) {
3791cb0ef41Sopenharmony_ci    DCHECK_NE(kNullAddress, isolate->isolate_data()->fast_c_call_caller_pc());
3801cb0ef41Sopenharmony_ci    type = StackFrame::Type::OPTIMIZED;
3811cb0ef41Sopenharmony_ci    top_frame_type_ = type;
3821cb0ef41Sopenharmony_ci    state.fp = fast_c_fp;
3831cb0ef41Sopenharmony_ci    state.sp = sp;
3841cb0ef41Sopenharmony_ci    state.pc_address = reinterpret_cast<Address*>(
3851cb0ef41Sopenharmony_ci        isolate->isolate_data()->fast_c_call_caller_pc_address());
3861cb0ef41Sopenharmony_ci    advance_frame = false;
3871cb0ef41Sopenharmony_ci  } else if (IsValidTop(top)) {
3881cb0ef41Sopenharmony_ci    type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
3891cb0ef41Sopenharmony_ci    top_frame_type_ = type;
3901cb0ef41Sopenharmony_ci  } else if (IsValidStackAddress(fp)) {
3911cb0ef41Sopenharmony_ci    DCHECK_NE(fp, kNullAddress);
3921cb0ef41Sopenharmony_ci    state.fp = fp;
3931cb0ef41Sopenharmony_ci    state.sp = sp;
3941cb0ef41Sopenharmony_ci    state.pc_address = StackFrame::ResolveReturnAddressLocation(
3951cb0ef41Sopenharmony_ci        reinterpret_cast<Address*>(CommonFrame::ComputePCAddress(fp)));
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci    // If the current PC is in a bytecode handler, the top stack frame isn't
3981cb0ef41Sopenharmony_ci    // the bytecode handler's frame and the top of stack or link register is a
3991cb0ef41Sopenharmony_ci    // return address into the interpreter entry trampoline, then we are likely
4001cb0ef41Sopenharmony_ci    // in a bytecode handler with elided frame. In that case, set the PC
4011cb0ef41Sopenharmony_ci    // properly and make sure we do not drop the frame.
4021cb0ef41Sopenharmony_ci    bool is_no_frame_bytecode_handler = false;
4031cb0ef41Sopenharmony_ci    if (IsNoFrameBytecodeHandlerPc(isolate, pc, fp)) {
4041cb0ef41Sopenharmony_ci      Address* tos_location = nullptr;
4051cb0ef41Sopenharmony_ci      if (top_link_register_) {
4061cb0ef41Sopenharmony_ci        tos_location = &top_link_register_;
4071cb0ef41Sopenharmony_ci      } else if (IsValidStackAddress(sp)) {
4081cb0ef41Sopenharmony_ci        MSAN_MEMORY_IS_INITIALIZED(sp, kSystemPointerSize);
4091cb0ef41Sopenharmony_ci        tos_location = reinterpret_cast<Address*>(sp);
4101cb0ef41Sopenharmony_ci      }
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci      if (IsInterpreterFramePc(isolate, *tos_location, &state)) {
4131cb0ef41Sopenharmony_ci        state.pc_address = tos_location;
4141cb0ef41Sopenharmony_ci        is_no_frame_bytecode_handler = true;
4151cb0ef41Sopenharmony_ci        advance_frame = false;
4161cb0ef41Sopenharmony_ci      }
4171cb0ef41Sopenharmony_ci    }
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_ci    // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
4201cb0ef41Sopenharmony_ci    // we check only that kMarkerOffset is within the stack bounds and do
4211cb0ef41Sopenharmony_ci    // compile time check that kContextOffset slot is pushed on the stack before
4221cb0ef41Sopenharmony_ci    // kMarkerOffset.
4231cb0ef41Sopenharmony_ci    STATIC_ASSERT(StandardFrameConstants::kFunctionOffset <
4241cb0ef41Sopenharmony_ci                  StandardFrameConstants::kContextOffset);
4251cb0ef41Sopenharmony_ci    Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
4261cb0ef41Sopenharmony_ci    if (IsValidStackAddress(frame_marker)) {
4271cb0ef41Sopenharmony_ci      if (is_no_frame_bytecode_handler) {
4281cb0ef41Sopenharmony_ci        type = StackFrame::INTERPRETED;
4291cb0ef41Sopenharmony_ci      } else {
4301cb0ef41Sopenharmony_ci        type = StackFrame::ComputeType(this, &state);
4311cb0ef41Sopenharmony_ci      }
4321cb0ef41Sopenharmony_ci      top_frame_type_ = type;
4331cb0ef41Sopenharmony_ci      MSAN_MEMORY_IS_INITIALIZED(
4341cb0ef41Sopenharmony_ci          fp + CommonFrameConstants::kContextOrFrameTypeOffset,
4351cb0ef41Sopenharmony_ci          kSystemPointerSize);
4361cb0ef41Sopenharmony_ci      Address type_or_context_address =
4371cb0ef41Sopenharmony_ci          Memory<Address>(fp + CommonFrameConstants::kContextOrFrameTypeOffset);
4381cb0ef41Sopenharmony_ci      if (!StackFrame::IsTypeMarker(type_or_context_address))
4391cb0ef41Sopenharmony_ci        top_context_address_ = type_or_context_address;
4401cb0ef41Sopenharmony_ci    } else {
4411cb0ef41Sopenharmony_ci      // Mark the frame as OPTIMIZED if we cannot determine its type.
4421cb0ef41Sopenharmony_ci      // We chose OPTIMIZED rather than INTERPRETED because it's closer to
4431cb0ef41Sopenharmony_ci      // the original value of StackFrame::JAVA_SCRIPT here, in that JAVA_SCRIPT
4441cb0ef41Sopenharmony_ci      // referred to full-codegen frames (now removed from the tree), and
4451cb0ef41Sopenharmony_ci      // OPTIMIZED refers to turbofan frames, both of which are generated
4461cb0ef41Sopenharmony_ci      // code. INTERPRETED frames refer to bytecode.
4471cb0ef41Sopenharmony_ci      // The frame anyways will be skipped.
4481cb0ef41Sopenharmony_ci      type = StackFrame::OPTIMIZED;
4491cb0ef41Sopenharmony_ci      // Top frame is incomplete so we cannot reliably determine its type.
4501cb0ef41Sopenharmony_ci      top_frame_type_ = StackFrame::NO_FRAME_TYPE;
4511cb0ef41Sopenharmony_ci    }
4521cb0ef41Sopenharmony_ci  } else {
4531cb0ef41Sopenharmony_ci    return;
4541cb0ef41Sopenharmony_ci  }
4551cb0ef41Sopenharmony_ci  frame_ = SingletonFor(type, &state);
4561cb0ef41Sopenharmony_ci  if (advance_frame && frame_) Advance();
4571cb0ef41Sopenharmony_ci}
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_cibool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const {
4601cb0ef41Sopenharmony_ci  Address c_entry_fp = Isolate::c_entry_fp(top);
4611cb0ef41Sopenharmony_ci  if (!IsValidExitFrame(c_entry_fp)) return false;
4621cb0ef41Sopenharmony_ci  // There should be at least one JS_ENTRY stack handler.
4631cb0ef41Sopenharmony_ci  Address handler = Isolate::handler(top);
4641cb0ef41Sopenharmony_ci  if (handler == kNullAddress) return false;
4651cb0ef41Sopenharmony_ci  // Check that there are no js frames on top of the native frames.
4661cb0ef41Sopenharmony_ci  return c_entry_fp < handler;
4671cb0ef41Sopenharmony_ci}
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_civoid SafeStackFrameIterator::AdvanceOneFrame() {
4701cb0ef41Sopenharmony_ci  DCHECK(!done());
4711cb0ef41Sopenharmony_ci  StackFrame* last_frame = frame_;
4721cb0ef41Sopenharmony_ci  Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci  // Before advancing to the next stack frame, perform pointer validity tests.
4751cb0ef41Sopenharmony_ci  if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
4761cb0ef41Sopenharmony_ci    frame_ = nullptr;
4771cb0ef41Sopenharmony_ci    return;
4781cb0ef41Sopenharmony_ci  }
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci  // Advance to the previous frame.
4811cb0ef41Sopenharmony_ci  StackFrame::State state;
4821cb0ef41Sopenharmony_ci  StackFrame::Type type = frame_->GetCallerState(&state);
4831cb0ef41Sopenharmony_ci  frame_ = SingletonFor(type, &state);
4841cb0ef41Sopenharmony_ci  if (!frame_) return;
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  // Check that we have actually moved to the previous frame in the stack.
4871cb0ef41Sopenharmony_ci  if (frame_->sp() <= last_sp || frame_->fp() <= last_fp) {
4881cb0ef41Sopenharmony_ci    frame_ = nullptr;
4891cb0ef41Sopenharmony_ci  }
4901cb0ef41Sopenharmony_ci}
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_cibool SafeStackFrameIterator::IsValidFrame(StackFrame* frame) const {
4931cb0ef41Sopenharmony_ci  return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
4941cb0ef41Sopenharmony_ci}
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_cibool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) {
4971cb0ef41Sopenharmony_ci  StackFrame::State state;
4981cb0ef41Sopenharmony_ci  if (frame->is_entry() || frame->is_construct_entry()) {
4991cb0ef41Sopenharmony_ci    // See EntryFrame::GetCallerState. It computes the caller FP address
5001cb0ef41Sopenharmony_ci    // and calls ExitFrame::GetStateForFramePointer on it. We need to be
5011cb0ef41Sopenharmony_ci    // sure that caller FP address is valid.
5021cb0ef41Sopenharmony_ci    Address caller_fp =
5031cb0ef41Sopenharmony_ci        Memory<Address>(frame->fp() + EntryFrameConstants::kCallerFPOffset);
5041cb0ef41Sopenharmony_ci    if (!IsValidExitFrame(caller_fp)) return false;
5051cb0ef41Sopenharmony_ci  }
5061cb0ef41Sopenharmony_ci  frame->ComputeCallerState(&state);
5071cb0ef41Sopenharmony_ci  return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
5081cb0ef41Sopenharmony_ci         SingletonFor(frame->GetCallerState(&state)) != nullptr;
5091cb0ef41Sopenharmony_ci}
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_cibool SafeStackFrameIterator::IsValidExitFrame(Address fp) const {
5121cb0ef41Sopenharmony_ci  if (!IsValidStackAddress(fp)) return false;
5131cb0ef41Sopenharmony_ci  Address sp = ExitFrame::ComputeStackPointer(fp);
5141cb0ef41Sopenharmony_ci  if (!IsValidStackAddress(sp)) return false;
5151cb0ef41Sopenharmony_ci  StackFrame::State state;
5161cb0ef41Sopenharmony_ci  ExitFrame::FillState(fp, sp, &state);
5171cb0ef41Sopenharmony_ci  MSAN_MEMORY_IS_INITIALIZED(state.pc_address, sizeof(state.pc_address));
5181cb0ef41Sopenharmony_ci  return *state.pc_address != kNullAddress;
5191cb0ef41Sopenharmony_ci}
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_civoid SafeStackFrameIterator::Advance() {
5221cb0ef41Sopenharmony_ci  while (true) {
5231cb0ef41Sopenharmony_ci    AdvanceOneFrame();
5241cb0ef41Sopenharmony_ci    if (done()) break;
5251cb0ef41Sopenharmony_ci    ExternalCallbackScope* last_callback_scope = nullptr;
5261cb0ef41Sopenharmony_ci    while (external_callback_scope_ != nullptr &&
5271cb0ef41Sopenharmony_ci           external_callback_scope_->scope_address() < frame_->fp()) {
5281cb0ef41Sopenharmony_ci      // As long as the setup of a frame is not atomic, we may happen to be
5291cb0ef41Sopenharmony_ci      // in an interval where an ExternalCallbackScope is already created,
5301cb0ef41Sopenharmony_ci      // but the frame is not yet entered. So we are actually observing
5311cb0ef41Sopenharmony_ci      // the previous frame.
5321cb0ef41Sopenharmony_ci      // Skip all the ExternalCallbackScope's that are below the current fp.
5331cb0ef41Sopenharmony_ci      last_callback_scope = external_callback_scope_;
5341cb0ef41Sopenharmony_ci      external_callback_scope_ = external_callback_scope_->previous();
5351cb0ef41Sopenharmony_ci    }
5361cb0ef41Sopenharmony_ci    if (frame_->is_java_script()) break;
5371cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
5381cb0ef41Sopenharmony_ci    if (frame_->is_wasm() || frame_->is_wasm_to_js() ||
5391cb0ef41Sopenharmony_ci        frame_->is_js_to_wasm()) {
5401cb0ef41Sopenharmony_ci      break;
5411cb0ef41Sopenharmony_ci    }
5421cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
5431cb0ef41Sopenharmony_ci    if (frame_->is_exit() || frame_->is_builtin_exit()) {
5441cb0ef41Sopenharmony_ci      // Some of the EXIT frames may have ExternalCallbackScope allocated on
5451cb0ef41Sopenharmony_ci      // top of them. In that case the scope corresponds to the first EXIT
5461cb0ef41Sopenharmony_ci      // frame beneath it. There may be other EXIT frames on top of the
5471cb0ef41Sopenharmony_ci      // ExternalCallbackScope, just skip them as we cannot collect any useful
5481cb0ef41Sopenharmony_ci      // information about them.
5491cb0ef41Sopenharmony_ci      if (last_callback_scope) {
5501cb0ef41Sopenharmony_ci        frame_->state_.pc_address =
5511cb0ef41Sopenharmony_ci            last_callback_scope->callback_entrypoint_address();
5521cb0ef41Sopenharmony_ci      }
5531cb0ef41Sopenharmony_ci      break;
5541cb0ef41Sopenharmony_ci    }
5551cb0ef41Sopenharmony_ci  }
5561cb0ef41Sopenharmony_ci}
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_cinamespace {
5611cb0ef41Sopenharmony_ciCode GetContainingCode(Isolate* isolate, Address pc) {
5621cb0ef41Sopenharmony_ci  return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
5631cb0ef41Sopenharmony_ci}
5641cb0ef41Sopenharmony_ci}  // namespace
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ciCode StackFrame::LookupCode() const {
5671cb0ef41Sopenharmony_ci  Code result = GetContainingCode(isolate(), pc());
5681cb0ef41Sopenharmony_ci  DCHECK_GE(pc(), result.InstructionStart(isolate(), pc()));
5691cb0ef41Sopenharmony_ci  DCHECK_LT(pc(), result.InstructionEnd(isolate(), pc()));
5701cb0ef41Sopenharmony_ci  return result;
5711cb0ef41Sopenharmony_ci}
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_civoid StackFrame::IteratePc(RootVisitor* v, Address* pc_address,
5741cb0ef41Sopenharmony_ci                           Address* constant_pool_address, Code holder) const {
5751cb0ef41Sopenharmony_ci  Address old_pc = ReadPC(pc_address);
5761cb0ef41Sopenharmony_ci  DCHECK(ReadOnlyHeap::Contains(holder) ||
5771cb0ef41Sopenharmony_ci         holder.GetHeap()->GcSafeCodeContains(holder, old_pc));
5781cb0ef41Sopenharmony_ci  unsigned pc_offset = holder.GetOffsetFromInstructionStart(isolate_, old_pc);
5791cb0ef41Sopenharmony_ci  Object code = holder;
5801cb0ef41Sopenharmony_ci  v->VisitRunningCode(FullObjectSlot(&code));
5811cb0ef41Sopenharmony_ci  if (code == holder) return;
5821cb0ef41Sopenharmony_ci  holder = Code::unchecked_cast(code);
5831cb0ef41Sopenharmony_ci  Address pc = holder.InstructionStart(isolate_, old_pc) + pc_offset;
5841cb0ef41Sopenharmony_ci  // TODO(v8:10026): avoid replacing a signed pointer.
5851cb0ef41Sopenharmony_ci  PointerAuthentication::ReplacePC(pc_address, pc, kSystemPointerSize);
5861cb0ef41Sopenharmony_ci  if (FLAG_enable_embedded_constant_pool && constant_pool_address) {
5871cb0ef41Sopenharmony_ci    *constant_pool_address = holder.constant_pool();
5881cb0ef41Sopenharmony_ci  }
5891cb0ef41Sopenharmony_ci}
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_civoid StackFrame::SetReturnAddressLocationResolver(
5921cb0ef41Sopenharmony_ci    ReturnAddressLocationResolver resolver) {
5931cb0ef41Sopenharmony_ci  DCHECK_NULL(return_address_location_resolver_);
5941cb0ef41Sopenharmony_ci  return_address_location_resolver_ = resolver;
5951cb0ef41Sopenharmony_ci}
5961cb0ef41Sopenharmony_ci
5971cb0ef41Sopenharmony_ciStackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
5981cb0ef41Sopenharmony_ci                                         State* state) {
5991cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6001cb0ef41Sopenharmony_ci  if (state->fp == kNullAddress) {
6011cb0ef41Sopenharmony_ci    DCHECK(FLAG_experimental_wasm_stack_switching);
6021cb0ef41Sopenharmony_ci    return NO_FRAME_TYPE;
6031cb0ef41Sopenharmony_ci  }
6041cb0ef41Sopenharmony_ci#endif
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci  MSAN_MEMORY_IS_INITIALIZED(
6071cb0ef41Sopenharmony_ci      state->fp + CommonFrameConstants::kContextOrFrameTypeOffset,
6081cb0ef41Sopenharmony_ci      kSystemPointerSize);
6091cb0ef41Sopenharmony_ci  intptr_t marker = Memory<intptr_t>(
6101cb0ef41Sopenharmony_ci      state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
6111cb0ef41Sopenharmony_ci  Address pc = StackFrame::ReadPC(state->pc_address);
6121cb0ef41Sopenharmony_ci  if (!iterator->can_access_heap_objects_) {
6131cb0ef41Sopenharmony_ci    // TODO(titzer): "can_access_heap_objects" is kind of bogus. It really
6141cb0ef41Sopenharmony_ci    // means that we are being called from the profiler, which can interrupt
6151cb0ef41Sopenharmony_ci    // the VM with a signal at any arbitrary instruction, with essentially
6161cb0ef41Sopenharmony_ci    // anything on the stack. So basically none of these checks are 100%
6171cb0ef41Sopenharmony_ci    // reliable.
6181cb0ef41Sopenharmony_ci    MSAN_MEMORY_IS_INITIALIZED(
6191cb0ef41Sopenharmony_ci        state->fp + StandardFrameConstants::kFunctionOffset,
6201cb0ef41Sopenharmony_ci        kSystemPointerSize);
6211cb0ef41Sopenharmony_ci    Object maybe_function = Object(
6221cb0ef41Sopenharmony_ci        Memory<Address>(state->fp + StandardFrameConstants::kFunctionOffset));
6231cb0ef41Sopenharmony_ci    if (!StackFrame::IsTypeMarker(marker)) {
6241cb0ef41Sopenharmony_ci      if (maybe_function.IsSmi()) {
6251cb0ef41Sopenharmony_ci        return NATIVE;
6261cb0ef41Sopenharmony_ci      } else if (IsInterpreterFramePc(iterator->isolate(), pc, state)) {
6271cb0ef41Sopenharmony_ci        return INTERPRETED;
6281cb0ef41Sopenharmony_ci      } else {
6291cb0ef41Sopenharmony_ci        return OPTIMIZED;
6301cb0ef41Sopenharmony_ci      }
6311cb0ef41Sopenharmony_ci    }
6321cb0ef41Sopenharmony_ci  } else {
6331cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6341cb0ef41Sopenharmony_ci    // If the {pc} does not point into WebAssembly code we can rely on the
6351cb0ef41Sopenharmony_ci    // returned {wasm_code} to be null and fall back to {GetContainingCode}.
6361cb0ef41Sopenharmony_ci    wasm::WasmCodeRefScope code_ref_scope;
6371cb0ef41Sopenharmony_ci    if (wasm::WasmCode* wasm_code =
6381cb0ef41Sopenharmony_ci            wasm::GetWasmCodeManager()->LookupCode(pc)) {
6391cb0ef41Sopenharmony_ci      switch (wasm_code->kind()) {
6401cb0ef41Sopenharmony_ci        case wasm::WasmCode::kWasmFunction:
6411cb0ef41Sopenharmony_ci          return WASM;
6421cb0ef41Sopenharmony_ci        case wasm::WasmCode::kWasmToCapiWrapper:
6431cb0ef41Sopenharmony_ci          return WASM_EXIT;
6441cb0ef41Sopenharmony_ci        case wasm::WasmCode::kWasmToJsWrapper:
6451cb0ef41Sopenharmony_ci          return WASM_TO_JS;
6461cb0ef41Sopenharmony_ci        default:
6471cb0ef41Sopenharmony_ci          UNREACHABLE();
6481cb0ef41Sopenharmony_ci      }
6491cb0ef41Sopenharmony_ci    }
6501cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci    // Look up the code object to figure out the type of the stack frame.
6531cb0ef41Sopenharmony_ci    Code code_obj = GetContainingCode(iterator->isolate(), pc);
6541cb0ef41Sopenharmony_ci    if (!code_obj.is_null()) {
6551cb0ef41Sopenharmony_ci      switch (code_obj.kind()) {
6561cb0ef41Sopenharmony_ci        case CodeKind::BUILTIN:
6571cb0ef41Sopenharmony_ci          if (StackFrame::IsTypeMarker(marker)) break;
6581cb0ef41Sopenharmony_ci          if (code_obj.is_interpreter_trampoline_builtin() ||
6591cb0ef41Sopenharmony_ci              // Frames for baseline entry trampolines on the stack are still
6601cb0ef41Sopenharmony_ci              // interpreted frames.
6611cb0ef41Sopenharmony_ci              code_obj.is_baseline_trampoline_builtin()) {
6621cb0ef41Sopenharmony_ci            return INTERPRETED;
6631cb0ef41Sopenharmony_ci          }
6641cb0ef41Sopenharmony_ci          if (code_obj.is_baseline_leave_frame_builtin()) {
6651cb0ef41Sopenharmony_ci            return BASELINE;
6661cb0ef41Sopenharmony_ci          }
6671cb0ef41Sopenharmony_ci          if (code_obj.is_turbofanned()) {
6681cb0ef41Sopenharmony_ci            // TODO(bmeurer): We treat frames for BUILTIN Code objects as
6691cb0ef41Sopenharmony_ci            // OptimizedFrame for now (all the builtins with JavaScript
6701cb0ef41Sopenharmony_ci            // linkage are actually generated with TurboFan currently, so
6711cb0ef41Sopenharmony_ci            // this is sound).
6721cb0ef41Sopenharmony_ci            return OPTIMIZED;
6731cb0ef41Sopenharmony_ci          }
6741cb0ef41Sopenharmony_ci          return BUILTIN;
6751cb0ef41Sopenharmony_ci        case CodeKind::TURBOFAN:
6761cb0ef41Sopenharmony_ci        case CodeKind::MAGLEV:
6771cb0ef41Sopenharmony_ci          return OPTIMIZED;
6781cb0ef41Sopenharmony_ci        case CodeKind::BASELINE:
6791cb0ef41Sopenharmony_ci          return Type::BASELINE;
6801cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6811cb0ef41Sopenharmony_ci        case CodeKind::JS_TO_WASM_FUNCTION:
6821cb0ef41Sopenharmony_ci          return JS_TO_WASM;
6831cb0ef41Sopenharmony_ci        case CodeKind::JS_TO_JS_FUNCTION:
6841cb0ef41Sopenharmony_ci          return STUB;
6851cb0ef41Sopenharmony_ci        case CodeKind::C_WASM_ENTRY:
6861cb0ef41Sopenharmony_ci          return C_WASM_ENTRY;
6871cb0ef41Sopenharmony_ci        case CodeKind::WASM_TO_JS_FUNCTION:
6881cb0ef41Sopenharmony_ci          return WASM_TO_JS;
6891cb0ef41Sopenharmony_ci        case CodeKind::WASM_FUNCTION:
6901cb0ef41Sopenharmony_ci        case CodeKind::WASM_TO_CAPI_FUNCTION:
6911cb0ef41Sopenharmony_ci          // Never appear as on-heap {Code} objects.
6921cb0ef41Sopenharmony_ci          UNREACHABLE();
6931cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
6941cb0ef41Sopenharmony_ci        default:
6951cb0ef41Sopenharmony_ci          // All other types should have an explicit marker
6961cb0ef41Sopenharmony_ci          break;
6971cb0ef41Sopenharmony_ci      }
6981cb0ef41Sopenharmony_ci    } else {
6991cb0ef41Sopenharmony_ci      return NATIVE;
7001cb0ef41Sopenharmony_ci    }
7011cb0ef41Sopenharmony_ci  }
7021cb0ef41Sopenharmony_ci  DCHECK(StackFrame::IsTypeMarker(marker));
7031cb0ef41Sopenharmony_ci  StackFrame::Type candidate = StackFrame::MarkerToType(marker);
7041cb0ef41Sopenharmony_ci  switch (candidate) {
7051cb0ef41Sopenharmony_ci    case ENTRY:
7061cb0ef41Sopenharmony_ci    case CONSTRUCT_ENTRY:
7071cb0ef41Sopenharmony_ci    case EXIT:
7081cb0ef41Sopenharmony_ci    case BUILTIN_CONTINUATION:
7091cb0ef41Sopenharmony_ci    case JAVA_SCRIPT_BUILTIN_CONTINUATION:
7101cb0ef41Sopenharmony_ci    case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
7111cb0ef41Sopenharmony_ci    case BUILTIN_EXIT:
7121cb0ef41Sopenharmony_ci    case STUB:
7131cb0ef41Sopenharmony_ci    case INTERNAL:
7141cb0ef41Sopenharmony_ci    case CONSTRUCT:
7151cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
7161cb0ef41Sopenharmony_ci    case WASM_TO_JS:
7171cb0ef41Sopenharmony_ci    case WASM:
7181cb0ef41Sopenharmony_ci    case WASM_COMPILE_LAZY:
7191cb0ef41Sopenharmony_ci    case WASM_EXIT:
7201cb0ef41Sopenharmony_ci    case WASM_DEBUG_BREAK:
7211cb0ef41Sopenharmony_ci    case JS_TO_WASM:
7221cb0ef41Sopenharmony_ci    case STACK_SWITCH:
7231cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
7241cb0ef41Sopenharmony_ci      return candidate;
7251cb0ef41Sopenharmony_ci    case OPTIMIZED:
7261cb0ef41Sopenharmony_ci    case INTERPRETED:
7271cb0ef41Sopenharmony_ci    default:
7281cb0ef41Sopenharmony_ci      // Unoptimized and optimized JavaScript frames, including
7291cb0ef41Sopenharmony_ci      // interpreted frames, should never have a StackFrame::Type
7301cb0ef41Sopenharmony_ci      // marker. If we find one, we're likely being called from the
7311cb0ef41Sopenharmony_ci      // profiler in a bogus stack frame.
7321cb0ef41Sopenharmony_ci      return NATIVE;
7331cb0ef41Sopenharmony_ci  }
7341cb0ef41Sopenharmony_ci}
7351cb0ef41Sopenharmony_ci
7361cb0ef41Sopenharmony_ci#ifdef DEBUG
7371cb0ef41Sopenharmony_cibool StackFrame::can_access_heap_objects() const {
7381cb0ef41Sopenharmony_ci  return iterator_->can_access_heap_objects_;
7391cb0ef41Sopenharmony_ci}
7401cb0ef41Sopenharmony_ci#endif
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_ciStackFrame::Type StackFrame::GetCallerState(State* state) const {
7431cb0ef41Sopenharmony_ci  ComputeCallerState(state);
7441cb0ef41Sopenharmony_ci  return ComputeType(iterator_, state);
7451cb0ef41Sopenharmony_ci}
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ciAddress CommonFrame::GetCallerStackPointer() const {
7481cb0ef41Sopenharmony_ci  return fp() + CommonFrameConstants::kCallerSPOffset;
7491cb0ef41Sopenharmony_ci}
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_civoid NativeFrame::ComputeCallerState(State* state) const {
7521cb0ef41Sopenharmony_ci  state->sp = caller_sp();
7531cb0ef41Sopenharmony_ci  state->fp = Memory<Address>(fp() + CommonFrameConstants::kCallerFPOffset);
7541cb0ef41Sopenharmony_ci  state->pc_address = ResolveReturnAddressLocation(
7551cb0ef41Sopenharmony_ci      reinterpret_cast<Address*>(fp() + CommonFrameConstants::kCallerPCOffset));
7561cb0ef41Sopenharmony_ci  state->callee_pc_address = nullptr;
7571cb0ef41Sopenharmony_ci  state->constant_pool_address = nullptr;
7581cb0ef41Sopenharmony_ci}
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ciCode EntryFrame::unchecked_code() const {
7611cb0ef41Sopenharmony_ci  return FromCodeT(isolate()->builtins()->code(Builtin::kJSEntry));
7621cb0ef41Sopenharmony_ci}
7631cb0ef41Sopenharmony_ci
7641cb0ef41Sopenharmony_civoid EntryFrame::ComputeCallerState(State* state) const {
7651cb0ef41Sopenharmony_ci  GetCallerState(state);
7661cb0ef41Sopenharmony_ci}
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ciStackFrame::Type EntryFrame::GetCallerState(State* state) const {
7691cb0ef41Sopenharmony_ci  const int offset = EntryFrameConstants::kCallerFPOffset;
7701cb0ef41Sopenharmony_ci  Address fp = Memory<Address>(this->fp() + offset);
7711cb0ef41Sopenharmony_ci  return ExitFrame::GetStateForFramePointer(fp, state);
7721cb0ef41Sopenharmony_ci}
7731cb0ef41Sopenharmony_ci
7741cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
7751cb0ef41Sopenharmony_ciStackFrame::Type CWasmEntryFrame::GetCallerState(State* state) const {
7761cb0ef41Sopenharmony_ci  const int offset = CWasmEntryFrameConstants::kCEntryFPOffset;
7771cb0ef41Sopenharmony_ci  Address fp = Memory<Address>(this->fp() + offset);
7781cb0ef41Sopenharmony_ci  return ExitFrame::GetStateForFramePointer(fp, state);
7791cb0ef41Sopenharmony_ci}
7801cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
7811cb0ef41Sopenharmony_ci
7821cb0ef41Sopenharmony_ciCode ConstructEntryFrame::unchecked_code() const {
7831cb0ef41Sopenharmony_ci  return FromCodeT(isolate()->builtins()->code(Builtin::kJSConstructEntry));
7841cb0ef41Sopenharmony_ci}
7851cb0ef41Sopenharmony_ci
7861cb0ef41Sopenharmony_civoid ExitFrame::ComputeCallerState(State* state) const {
7871cb0ef41Sopenharmony_ci  // Set up the caller state.
7881cb0ef41Sopenharmony_ci  state->sp = caller_sp();
7891cb0ef41Sopenharmony_ci  state->fp = Memory<Address>(fp() + ExitFrameConstants::kCallerFPOffset);
7901cb0ef41Sopenharmony_ci  state->pc_address = ResolveReturnAddressLocation(
7911cb0ef41Sopenharmony_ci      reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
7921cb0ef41Sopenharmony_ci  state->callee_pc_address = nullptr;
7931cb0ef41Sopenharmony_ci  if (FLAG_enable_embedded_constant_pool) {
7941cb0ef41Sopenharmony_ci    state->constant_pool_address = reinterpret_cast<Address*>(
7951cb0ef41Sopenharmony_ci        fp() + ExitFrameConstants::kConstantPoolOffset);
7961cb0ef41Sopenharmony_ci  }
7971cb0ef41Sopenharmony_ci}
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_civoid ExitFrame::Iterate(RootVisitor* v) const {
8001cb0ef41Sopenharmony_ci  // The arguments are traversed as part of the expression stack of
8011cb0ef41Sopenharmony_ci  // the calling frame.
8021cb0ef41Sopenharmony_ci  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
8031cb0ef41Sopenharmony_ci}
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ciStackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
8061cb0ef41Sopenharmony_ci  if (fp == 0) return NO_FRAME_TYPE;
8071cb0ef41Sopenharmony_ci  StackFrame::Type type = ComputeFrameType(fp);
8081cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
8091cb0ef41Sopenharmony_ci  Address sp = type == WASM_EXIT ? WasmExitFrame::ComputeStackPointer(fp)
8101cb0ef41Sopenharmony_ci                                 : ExitFrame::ComputeStackPointer(fp);
8111cb0ef41Sopenharmony_ci#else
8121cb0ef41Sopenharmony_ci  Address sp = ExitFrame::ComputeStackPointer(fp);
8131cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
8141cb0ef41Sopenharmony_ci  FillState(fp, sp, state);
8151cb0ef41Sopenharmony_ci  DCHECK_NE(*state->pc_address, kNullAddress);
8161cb0ef41Sopenharmony_ci  return type;
8171cb0ef41Sopenharmony_ci}
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ciStackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
8201cb0ef41Sopenharmony_ci  // Distinguish between between regular and builtin exit frames.
8211cb0ef41Sopenharmony_ci  // Default to EXIT in all hairy cases (e.g., when called from profiler).
8221cb0ef41Sopenharmony_ci  const int offset = ExitFrameConstants::kFrameTypeOffset;
8231cb0ef41Sopenharmony_ci  Object marker(Memory<Address>(fp + offset));
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci  if (!marker.IsSmi()) {
8261cb0ef41Sopenharmony_ci    return EXIT;
8271cb0ef41Sopenharmony_ci  }
8281cb0ef41Sopenharmony_ci
8291cb0ef41Sopenharmony_ci  intptr_t marker_int = bit_cast<intptr_t>(marker);
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ci  StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1);
8321cb0ef41Sopenharmony_ci  switch (frame_type) {
8331cb0ef41Sopenharmony_ci    case BUILTIN_EXIT:
8341cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
8351cb0ef41Sopenharmony_ci    case WASM_EXIT:
8361cb0ef41Sopenharmony_ci    case STACK_SWITCH:
8371cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
8381cb0ef41Sopenharmony_ci      return frame_type;
8391cb0ef41Sopenharmony_ci    default:
8401cb0ef41Sopenharmony_ci      return EXIT;
8411cb0ef41Sopenharmony_ci  }
8421cb0ef41Sopenharmony_ci}
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ciAddress ExitFrame::ComputeStackPointer(Address fp) {
8451cb0ef41Sopenharmony_ci  MSAN_MEMORY_IS_INITIALIZED(fp + ExitFrameConstants::kSPOffset,
8461cb0ef41Sopenharmony_ci                             kSystemPointerSize);
8471cb0ef41Sopenharmony_ci  return Memory<Address>(fp + ExitFrameConstants::kSPOffset);
8481cb0ef41Sopenharmony_ci}
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
8511cb0ef41Sopenharmony_ciAddress WasmExitFrame::ComputeStackPointer(Address fp) {
8521cb0ef41Sopenharmony_ci  // For WASM_EXIT frames, {sp} is only needed for finding the PC slot,
8531cb0ef41Sopenharmony_ci  // everything else is handled via safepoint information.
8541cb0ef41Sopenharmony_ci  Address sp = fp + WasmExitFrameConstants::kWasmInstanceOffset;
8551cb0ef41Sopenharmony_ci  DCHECK_EQ(sp - 1 * kPCOnStackSize,
8561cb0ef41Sopenharmony_ci            fp + WasmExitFrameConstants::kCallingPCOffset);
8571cb0ef41Sopenharmony_ci  return sp;
8581cb0ef41Sopenharmony_ci}
8591cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
8601cb0ef41Sopenharmony_ci
8611cb0ef41Sopenharmony_civoid ExitFrame::FillState(Address fp, Address sp, State* state) {
8621cb0ef41Sopenharmony_ci  state->sp = sp;
8631cb0ef41Sopenharmony_ci  state->fp = fp;
8641cb0ef41Sopenharmony_ci  state->pc_address = ResolveReturnAddressLocation(
8651cb0ef41Sopenharmony_ci      reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
8661cb0ef41Sopenharmony_ci  state->callee_pc_address = nullptr;
8671cb0ef41Sopenharmony_ci  // The constant pool recorded in the exit frame is not associated
8681cb0ef41Sopenharmony_ci  // with the pc in this state (the return address into a C entry
8691cb0ef41Sopenharmony_ci  // stub).  ComputeCallerState will retrieve the constant pool
8701cb0ef41Sopenharmony_ci  // together with the associated caller pc.
8711cb0ef41Sopenharmony_ci  state->constant_pool_address = nullptr;
8721cb0ef41Sopenharmony_ci}
8731cb0ef41Sopenharmony_ci
8741cb0ef41Sopenharmony_civoid BuiltinExitFrame::Summarize(std::vector<FrameSummary>* frames) const {
8751cb0ef41Sopenharmony_ci  DCHECK(frames->empty());
8761cb0ef41Sopenharmony_ci  Handle<FixedArray> parameters = GetParameters();
8771cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8781cb0ef41Sopenharmony_ci  Code code = LookupCode();
8791cb0ef41Sopenharmony_ci  int code_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
8801cb0ef41Sopenharmony_ci  FrameSummary::JavaScriptFrameSummary summary(
8811cb0ef41Sopenharmony_ci      isolate(), receiver(), function(), AbstractCode::cast(code), code_offset,
8821cb0ef41Sopenharmony_ci      IsConstructor(), *parameters);
8831cb0ef41Sopenharmony_ci  frames->push_back(summary);
8841cb0ef41Sopenharmony_ci}
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ciJSFunction BuiltinExitFrame::function() const {
8871cb0ef41Sopenharmony_ci  return JSFunction::cast(target_slot_object());
8881cb0ef41Sopenharmony_ci}
8891cb0ef41Sopenharmony_ci
8901cb0ef41Sopenharmony_ciObject BuiltinExitFrame::receiver() const { return receiver_slot_object(); }
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ciObject BuiltinExitFrame::GetParameter(int i) const {
8931cb0ef41Sopenharmony_ci  DCHECK(i >= 0 && i < ComputeParametersCount());
8941cb0ef41Sopenharmony_ci  int offset =
8951cb0ef41Sopenharmony_ci      BuiltinExitFrameConstants::kFirstArgumentOffset + i * kSystemPointerSize;
8961cb0ef41Sopenharmony_ci  return Object(Memory<Address>(fp() + offset));
8971cb0ef41Sopenharmony_ci}
8981cb0ef41Sopenharmony_ci
8991cb0ef41Sopenharmony_ciint BuiltinExitFrame::ComputeParametersCount() const {
9001cb0ef41Sopenharmony_ci  Object argc_slot = argc_slot_object();
9011cb0ef41Sopenharmony_ci  DCHECK(argc_slot.IsSmi());
9021cb0ef41Sopenharmony_ci  // Argc also counts the receiver, target, new target, and argc itself as args,
9031cb0ef41Sopenharmony_ci  // therefore the real argument count is argc - 4.
9041cb0ef41Sopenharmony_ci  int argc = Smi::ToInt(argc_slot) - 4;
9051cb0ef41Sopenharmony_ci  DCHECK_GE(argc, 0);
9061cb0ef41Sopenharmony_ci  return argc;
9071cb0ef41Sopenharmony_ci}
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_ciHandle<FixedArray> BuiltinExitFrame::GetParameters() const {
9101cb0ef41Sopenharmony_ci  if (V8_LIKELY(!FLAG_detailed_error_stack_trace)) {
9111cb0ef41Sopenharmony_ci    return isolate()->factory()->empty_fixed_array();
9121cb0ef41Sopenharmony_ci  }
9131cb0ef41Sopenharmony_ci  int param_count = ComputeParametersCount();
9141cb0ef41Sopenharmony_ci  auto parameters = isolate()->factory()->NewFixedArray(param_count);
9151cb0ef41Sopenharmony_ci  for (int i = 0; i < param_count; i++) {
9161cb0ef41Sopenharmony_ci    parameters->set(i, GetParameter(i));
9171cb0ef41Sopenharmony_ci  }
9181cb0ef41Sopenharmony_ci  return parameters;
9191cb0ef41Sopenharmony_ci}
9201cb0ef41Sopenharmony_ci
9211cb0ef41Sopenharmony_cibool BuiltinExitFrame::IsConstructor() const {
9221cb0ef41Sopenharmony_ci  return !new_target_slot_object().IsUndefined(isolate());
9231cb0ef41Sopenharmony_ci}
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_cinamespace {
9261cb0ef41Sopenharmony_civoid PrintIndex(StringStream* accumulator, StackFrame::PrintMode mode,
9271cb0ef41Sopenharmony_ci                int index) {
9281cb0ef41Sopenharmony_ci  accumulator->Add((mode == StackFrame::OVERVIEW) ? "%5d: " : "[%d]: ", index);
9291cb0ef41Sopenharmony_ci}
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_ciconst char* StringForStackFrameType(StackFrame::Type type) {
9321cb0ef41Sopenharmony_ci  switch (type) {
9331cb0ef41Sopenharmony_ci#define CASE(value, name) \
9341cb0ef41Sopenharmony_ci  case StackFrame::value: \
9351cb0ef41Sopenharmony_ci    return #name;
9361cb0ef41Sopenharmony_ci    STACK_FRAME_TYPE_LIST(CASE)
9371cb0ef41Sopenharmony_ci#undef CASE
9381cb0ef41Sopenharmony_ci    default:
9391cb0ef41Sopenharmony_ci      UNREACHABLE();
9401cb0ef41Sopenharmony_ci  }
9411cb0ef41Sopenharmony_ci}
9421cb0ef41Sopenharmony_ci}  // namespace
9431cb0ef41Sopenharmony_ci
9441cb0ef41Sopenharmony_civoid StackFrame::Print(StringStream* accumulator, PrintMode mode,
9451cb0ef41Sopenharmony_ci                       int index) const {
9461cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
9471cb0ef41Sopenharmony_ci  PrintIndex(accumulator, mode, index);
9481cb0ef41Sopenharmony_ci  accumulator->Add(StringForStackFrameType(type()));
9491cb0ef41Sopenharmony_ci  accumulator->Add(" [pc: %p]\n", reinterpret_cast<void*>(pc()));
9501cb0ef41Sopenharmony_ci}
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_civoid BuiltinExitFrame::Print(StringStream* accumulator, PrintMode mode,
9531cb0ef41Sopenharmony_ci                             int index) const {
9541cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
9551cb0ef41Sopenharmony_ci  Object receiver = this->receiver();
9561cb0ef41Sopenharmony_ci  JSFunction function = this->function();
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ci  accumulator->PrintSecurityTokenIfChanged(function);
9591cb0ef41Sopenharmony_ci  PrintIndex(accumulator, mode, index);
9601cb0ef41Sopenharmony_ci  accumulator->Add("builtin exit frame: ");
9611cb0ef41Sopenharmony_ci  Code code;
9621cb0ef41Sopenharmony_ci  if (IsConstructor()) accumulator->Add("new ");
9631cb0ef41Sopenharmony_ci  accumulator->PrintFunction(function, receiver, &code);
9641cb0ef41Sopenharmony_ci
9651cb0ef41Sopenharmony_ci  accumulator->Add("(this=%o", receiver);
9661cb0ef41Sopenharmony_ci
9671cb0ef41Sopenharmony_ci  // Print the parameters.
9681cb0ef41Sopenharmony_ci  int parameters_count = ComputeParametersCount();
9691cb0ef41Sopenharmony_ci  for (int i = 0; i < parameters_count; i++) {
9701cb0ef41Sopenharmony_ci    accumulator->Add(",%o", GetParameter(i));
9711cb0ef41Sopenharmony_ci  }
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_ci  accumulator->Add(")\n\n");
9741cb0ef41Sopenharmony_ci}
9751cb0ef41Sopenharmony_ci
9761cb0ef41Sopenharmony_ciAddress CommonFrame::GetExpressionAddress(int n) const {
9771cb0ef41Sopenharmony_ci  const int offset = StandardFrameConstants::kExpressionsOffset;
9781cb0ef41Sopenharmony_ci  return fp() + offset - n * kSystemPointerSize;
9791cb0ef41Sopenharmony_ci}
9801cb0ef41Sopenharmony_ci
9811cb0ef41Sopenharmony_ciAddress UnoptimizedFrame::GetExpressionAddress(int n) const {
9821cb0ef41Sopenharmony_ci  const int offset = UnoptimizedFrameConstants::kExpressionsOffset;
9831cb0ef41Sopenharmony_ci  return fp() + offset - n * kSystemPointerSize;
9841cb0ef41Sopenharmony_ci}
9851cb0ef41Sopenharmony_ci
9861cb0ef41Sopenharmony_ciObject CommonFrame::context() const {
9871cb0ef41Sopenharmony_ci  return ReadOnlyRoots(isolate()).undefined_value();
9881cb0ef41Sopenharmony_ci}
9891cb0ef41Sopenharmony_ci
9901cb0ef41Sopenharmony_ciint CommonFrame::position() const {
9911cb0ef41Sopenharmony_ci  Code code = LookupCode();
9921cb0ef41Sopenharmony_ci  int code_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
9931cb0ef41Sopenharmony_ci  return AbstractCode::cast(code).SourcePosition(code_offset);
9941cb0ef41Sopenharmony_ci}
9951cb0ef41Sopenharmony_ci
9961cb0ef41Sopenharmony_ciint CommonFrame::ComputeExpressionsCount() const {
9971cb0ef41Sopenharmony_ci  Address base = GetExpressionAddress(0);
9981cb0ef41Sopenharmony_ci  Address limit = sp() - kSystemPointerSize;
9991cb0ef41Sopenharmony_ci  DCHECK(base >= limit);  // stack grows downwards
10001cb0ef41Sopenharmony_ci  // Include register-allocated locals in number of expressions.
10011cb0ef41Sopenharmony_ci  return static_cast<int>((base - limit) / kSystemPointerSize);
10021cb0ef41Sopenharmony_ci}
10031cb0ef41Sopenharmony_ci
10041cb0ef41Sopenharmony_civoid CommonFrame::ComputeCallerState(State* state) const {
10051cb0ef41Sopenharmony_ci  state->fp = caller_fp();
10061cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
10071cb0ef41Sopenharmony_ci  if (state->fp == kNullAddress) {
10081cb0ef41Sopenharmony_ci    // An empty FP signals the first frame of a stack segment. The caller is
10091cb0ef41Sopenharmony_ci    // on a different stack, or is unbound (suspended stack).
10101cb0ef41Sopenharmony_ci    DCHECK(FLAG_experimental_wasm_stack_switching);
10111cb0ef41Sopenharmony_ci    return;
10121cb0ef41Sopenharmony_ci  }
10131cb0ef41Sopenharmony_ci#endif
10141cb0ef41Sopenharmony_ci  state->sp = caller_sp();
10151cb0ef41Sopenharmony_ci  state->pc_address = ResolveReturnAddressLocation(
10161cb0ef41Sopenharmony_ci      reinterpret_cast<Address*>(ComputePCAddress(fp())));
10171cb0ef41Sopenharmony_ci  state->callee_fp = fp();
10181cb0ef41Sopenharmony_ci  state->callee_pc_address = pc_address();
10191cb0ef41Sopenharmony_ci  state->constant_pool_address =
10201cb0ef41Sopenharmony_ci      reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
10211cb0ef41Sopenharmony_ci}
10221cb0ef41Sopenharmony_ci
10231cb0ef41Sopenharmony_civoid CommonFrame::Summarize(std::vector<FrameSummary>* functions) const {
10241cb0ef41Sopenharmony_ci  // This should only be called on frames which override this method.
10251cb0ef41Sopenharmony_ci  UNREACHABLE();
10261cb0ef41Sopenharmony_ci}
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_civoid CommonFrame::IterateCompiledFrame(RootVisitor* v) const {
10291cb0ef41Sopenharmony_ci  // Make sure that we're not doing "safe" stack frame iteration. We cannot
10301cb0ef41Sopenharmony_ci  // possibly find pointers in optimized frames in that state.
10311cb0ef41Sopenharmony_ci  DCHECK(can_access_heap_objects());
10321cb0ef41Sopenharmony_ci
10331cb0ef41Sopenharmony_ci  // Find the code and compute the safepoint information.
10341cb0ef41Sopenharmony_ci  Address inner_pointer = pc();
10351cb0ef41Sopenharmony_ci  SafepointEntry safepoint_entry;
10361cb0ef41Sopenharmony_ci  uint32_t stack_slots = 0;
10371cb0ef41Sopenharmony_ci  Code code;
10381cb0ef41Sopenharmony_ci  bool has_tagged_outgoing_params = false;
10391cb0ef41Sopenharmony_ci  uint16_t first_tagged_parameter_slot = 0;
10401cb0ef41Sopenharmony_ci  uint16_t num_tagged_parameter_slots = 0;
10411cb0ef41Sopenharmony_ci  bool is_wasm = false;
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
10441cb0ef41Sopenharmony_ci  bool has_wasm_feedback_slot = false;
10451cb0ef41Sopenharmony_ci  if (auto* wasm_code = wasm::GetWasmCodeManager()->LookupCode(inner_pointer)) {
10461cb0ef41Sopenharmony_ci    is_wasm = true;
10471cb0ef41Sopenharmony_ci    SafepointTable table(wasm_code);
10481cb0ef41Sopenharmony_ci    safepoint_entry = table.FindEntry(inner_pointer);
10491cb0ef41Sopenharmony_ci    stack_slots = wasm_code->stack_slots();
10501cb0ef41Sopenharmony_ci    has_tagged_outgoing_params =
10511cb0ef41Sopenharmony_ci        wasm_code->kind() != wasm::WasmCode::kWasmFunction &&
10521cb0ef41Sopenharmony_ci        wasm_code->kind() != wasm::WasmCode::kWasmToCapiWrapper;
10531cb0ef41Sopenharmony_ci    first_tagged_parameter_slot = wasm_code->first_tagged_parameter_slot();
10541cb0ef41Sopenharmony_ci    num_tagged_parameter_slots = wasm_code->num_tagged_parameter_slots();
10551cb0ef41Sopenharmony_ci    if (wasm_code->is_liftoff() && FLAG_wasm_speculative_inlining) {
10561cb0ef41Sopenharmony_ci      has_wasm_feedback_slot = true;
10571cb0ef41Sopenharmony_ci    }
10581cb0ef41Sopenharmony_ci  }
10591cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ci  if (!is_wasm) {
10621cb0ef41Sopenharmony_ci    InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
10631cb0ef41Sopenharmony_ci        isolate()->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
10641cb0ef41Sopenharmony_ci    if (!entry->safepoint_entry.is_initialized()) {
10651cb0ef41Sopenharmony_ci      entry->safepoint_entry =
10661cb0ef41Sopenharmony_ci          entry->code.GetSafepointEntry(isolate(), inner_pointer);
10671cb0ef41Sopenharmony_ci      DCHECK(entry->safepoint_entry.is_initialized());
10681cb0ef41Sopenharmony_ci    } else {
10691cb0ef41Sopenharmony_ci      DCHECK_EQ(entry->safepoint_entry,
10701cb0ef41Sopenharmony_ci                entry->code.GetSafepointEntry(isolate(), inner_pointer));
10711cb0ef41Sopenharmony_ci    }
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci    code = entry->code;
10741cb0ef41Sopenharmony_ci    safepoint_entry = entry->safepoint_entry;
10751cb0ef41Sopenharmony_ci    stack_slots = code.stack_slots();
10761cb0ef41Sopenharmony_ci
10771cb0ef41Sopenharmony_ci    has_tagged_outgoing_params = code.has_tagged_outgoing_params();
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
10801cb0ef41Sopenharmony_ci    // With inlined JS-to-Wasm calls, we can be in an OptimizedFrame and
10811cb0ef41Sopenharmony_ci    // directly call a Wasm function from JavaScript. In this case the
10821cb0ef41Sopenharmony_ci    // parameters we pass to the callee are not tagged.
10831cb0ef41Sopenharmony_ci    wasm::WasmCode* wasm_callee =
10841cb0ef41Sopenharmony_ci        wasm::GetWasmCodeManager()->LookupCode(callee_pc());
10851cb0ef41Sopenharmony_ci    bool is_wasm_call = (wasm_callee != nullptr);
10861cb0ef41Sopenharmony_ci    if (is_wasm_call) has_tagged_outgoing_params = false;
10871cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
10881cb0ef41Sopenharmony_ci  }
10891cb0ef41Sopenharmony_ci
10901cb0ef41Sopenharmony_ci  // Determine the fixed header and spill slot area size.
10911cb0ef41Sopenharmony_ci  int frame_header_size = StandardFrameConstants::kFixedFrameSizeFromFp;
10921cb0ef41Sopenharmony_ci  intptr_t marker =
10931cb0ef41Sopenharmony_ci      Memory<intptr_t>(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
10941cb0ef41Sopenharmony_ci  bool typed_frame = StackFrame::IsTypeMarker(marker);
10951cb0ef41Sopenharmony_ci  if (typed_frame) {
10961cb0ef41Sopenharmony_ci    StackFrame::Type candidate = StackFrame::MarkerToType(marker);
10971cb0ef41Sopenharmony_ci    switch (candidate) {
10981cb0ef41Sopenharmony_ci      case ENTRY:
10991cb0ef41Sopenharmony_ci      case CONSTRUCT_ENTRY:
11001cb0ef41Sopenharmony_ci      case EXIT:
11011cb0ef41Sopenharmony_ci      case BUILTIN_CONTINUATION:
11021cb0ef41Sopenharmony_ci      case JAVA_SCRIPT_BUILTIN_CONTINUATION:
11031cb0ef41Sopenharmony_ci      case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
11041cb0ef41Sopenharmony_ci      case BUILTIN_EXIT:
11051cb0ef41Sopenharmony_ci      case STUB:
11061cb0ef41Sopenharmony_ci      case INTERNAL:
11071cb0ef41Sopenharmony_ci      case CONSTRUCT:
11081cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
11091cb0ef41Sopenharmony_ci      case JS_TO_WASM:
11101cb0ef41Sopenharmony_ci      case STACK_SWITCH:
11111cb0ef41Sopenharmony_ci      case C_WASM_ENTRY:
11121cb0ef41Sopenharmony_ci      case WASM_DEBUG_BREAK:
11131cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
11141cb0ef41Sopenharmony_ci        frame_header_size = TypedFrameConstants::kFixedFrameSizeFromFp;
11151cb0ef41Sopenharmony_ci        break;
11161cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
11171cb0ef41Sopenharmony_ci      case WASM_TO_JS:
11181cb0ef41Sopenharmony_ci      case WASM:
11191cb0ef41Sopenharmony_ci      case WASM_COMPILE_LAZY:
11201cb0ef41Sopenharmony_ci        frame_header_size = WasmFrameConstants::kFixedFrameSizeFromFp;
11211cb0ef41Sopenharmony_ci        if (has_wasm_feedback_slot) frame_header_size += kSystemPointerSize;
11221cb0ef41Sopenharmony_ci        break;
11231cb0ef41Sopenharmony_ci      case WASM_EXIT:
11241cb0ef41Sopenharmony_ci        // The last value in the frame header is the calling PC, which should
11251cb0ef41Sopenharmony_ci        // not be visited.
11261cb0ef41Sopenharmony_ci        static_assert(WasmExitFrameConstants::kFixedSlotCountFromFp ==
11271cb0ef41Sopenharmony_ci                          WasmFrameConstants::kFixedSlotCountFromFp + 1,
11281cb0ef41Sopenharmony_ci                      "WasmExitFrame has one slot more than WasmFrame");
11291cb0ef41Sopenharmony_ci        frame_header_size = WasmFrameConstants::kFixedFrameSizeFromFp;
11301cb0ef41Sopenharmony_ci        break;
11311cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
11321cb0ef41Sopenharmony_ci      case OPTIMIZED:
11331cb0ef41Sopenharmony_ci      case INTERPRETED:
11341cb0ef41Sopenharmony_ci      case BASELINE:
11351cb0ef41Sopenharmony_ci      case BUILTIN:
11361cb0ef41Sopenharmony_ci        // These frame types have a context, but they are actually stored
11371cb0ef41Sopenharmony_ci        // in the place on the stack that one finds the frame type.
11381cb0ef41Sopenharmony_ci        UNREACHABLE();
11391cb0ef41Sopenharmony_ci      case NATIVE:
11401cb0ef41Sopenharmony_ci      case NO_FRAME_TYPE:
11411cb0ef41Sopenharmony_ci      case NUMBER_OF_TYPES:
11421cb0ef41Sopenharmony_ci      case MANUAL:
11431cb0ef41Sopenharmony_ci        UNREACHABLE();
11441cb0ef41Sopenharmony_ci    }
11451cb0ef41Sopenharmony_ci  }
11461cb0ef41Sopenharmony_ci
11471cb0ef41Sopenharmony_ci  // slot_space holds the actual number of spill slots, without fixed frame
11481cb0ef41Sopenharmony_ci  // slots.
11491cb0ef41Sopenharmony_ci  const uint32_t slot_space =
11501cb0ef41Sopenharmony_ci      stack_slots * kSystemPointerSize -
11511cb0ef41Sopenharmony_ci      (frame_header_size + StandardFrameConstants::kFixedFrameSizeAboveFp);
11521cb0ef41Sopenharmony_ci
11531cb0ef41Sopenharmony_ci  // base <= limit.
11541cb0ef41Sopenharmony_ci  // Fixed frame slots.
11551cb0ef41Sopenharmony_ci  FullObjectSlot frame_header_base(&Memory<Address>(fp() - frame_header_size));
11561cb0ef41Sopenharmony_ci  FullObjectSlot frame_header_limit(
11571cb0ef41Sopenharmony_ci      &Memory<Address>(fp() - StandardFrameConstants::kCPSlotSize));
11581cb0ef41Sopenharmony_ci  // Parameters passed to the callee.
11591cb0ef41Sopenharmony_ci  FullObjectSlot parameters_base(&Memory<Address>(sp()));
11601cb0ef41Sopenharmony_ci  FullObjectSlot parameters_limit(frame_header_base.address() - slot_space);
11611cb0ef41Sopenharmony_ci  // Spill slots are in the region ]frame_header_base, parameters_limit];
11621cb0ef41Sopenharmony_ci
11631cb0ef41Sopenharmony_ci  // Visit the rest of the parameters if they are tagged.
11641cb0ef41Sopenharmony_ci  if (has_tagged_outgoing_params) {
11651cb0ef41Sopenharmony_ci    v->VisitRootPointers(Root::kStackRoots, nullptr, parameters_base,
11661cb0ef41Sopenharmony_ci                         parameters_limit);
11671cb0ef41Sopenharmony_ci  }
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_ci  // Visit pointer spill slots and locals.
11701cb0ef41Sopenharmony_ci  DCHECK_GE((stack_slots + kBitsPerByte) / kBitsPerByte,
11711cb0ef41Sopenharmony_ci            safepoint_entry.tagged_slots().size());
11721cb0ef41Sopenharmony_ci  int slot_offset = 0;
11731cb0ef41Sopenharmony_ci  PtrComprCageBase cage_base(isolate());
11741cb0ef41Sopenharmony_ci  for (uint8_t bits : safepoint_entry.tagged_slots()) {
11751cb0ef41Sopenharmony_ci    while (bits) {
11761cb0ef41Sopenharmony_ci      const int bit = base::bits::CountTrailingZeros(bits);
11771cb0ef41Sopenharmony_ci      bits &= ~(1 << bit);
11781cb0ef41Sopenharmony_ci      FullObjectSlot spill_slot = parameters_limit + slot_offset + bit;
11791cb0ef41Sopenharmony_ci#ifdef V8_COMPRESS_POINTERS
11801cb0ef41Sopenharmony_ci      // Spill slots may contain compressed values in which case the upper
11811cb0ef41Sopenharmony_ci      // 32-bits will contain zeros. In order to simplify handling of such
11821cb0ef41Sopenharmony_ci      // slots in GC we ensure that the slot always contains full value.
11831cb0ef41Sopenharmony_ci
11841cb0ef41Sopenharmony_ci      // The spill slot may actually contain weak references so we load/store
11851cb0ef41Sopenharmony_ci      // values using spill_slot.location() in order to avoid dealing with
11861cb0ef41Sopenharmony_ci      // FullMaybeObjectSlots here.
11871cb0ef41Sopenharmony_ci      if (V8_EXTERNAL_CODE_SPACE_BOOL) {
11881cb0ef41Sopenharmony_ci        // When external code space is enabled the spill slot could contain both
11891cb0ef41Sopenharmony_ci        // Code and non-Code references, which have different cage bases. So
11901cb0ef41Sopenharmony_ci        // unconditional decompression of the value might corrupt Code pointers.
11911cb0ef41Sopenharmony_ci        // However, given that
11921cb0ef41Sopenharmony_ci        // 1) the Code pointers are never compressed by design (because
11931cb0ef41Sopenharmony_ci        //    otherwise we wouldn't know which cage base to apply for
11941cb0ef41Sopenharmony_ci        //    decompression, see respective DCHECKs in
11951cb0ef41Sopenharmony_ci        //    RelocInfo::target_object()),
11961cb0ef41Sopenharmony_ci        // 2) there's no need to update the upper part of the full pointer
11971cb0ef41Sopenharmony_ci        //    because if it was there then it'll stay the same,
11981cb0ef41Sopenharmony_ci        // we can avoid updating upper part of the spill slot if it already
11991cb0ef41Sopenharmony_ci        // contains full value.
12001cb0ef41Sopenharmony_ci        // TODO(v8:11880): Remove this special handling by enforcing builtins
12011cb0ef41Sopenharmony_ci        // to use CodeTs instead of Code objects.
12021cb0ef41Sopenharmony_ci        Address value = *spill_slot.location();
12031cb0ef41Sopenharmony_ci        if (!HAS_SMI_TAG(value) && value <= 0xffffffff) {
12041cb0ef41Sopenharmony_ci          // We don't need to update smi values or full pointers.
12051cb0ef41Sopenharmony_ci          *spill_slot.location() =
12061cb0ef41Sopenharmony_ci              DecompressTaggedPointer(cage_base, static_cast<Tagged_t>(value));
12071cb0ef41Sopenharmony_ci          if (DEBUG_BOOL) {
12081cb0ef41Sopenharmony_ci            // Ensure that the spill slot contains correct heap object.
12091cb0ef41Sopenharmony_ci            HeapObject raw = HeapObject::cast(Object(*spill_slot.location()));
12101cb0ef41Sopenharmony_ci            MapWord map_word = raw.map_word(cage_base, kRelaxedLoad);
12111cb0ef41Sopenharmony_ci            HeapObject forwarded = map_word.IsForwardingAddress()
12121cb0ef41Sopenharmony_ci                                       ? map_word.ToForwardingAddress()
12131cb0ef41Sopenharmony_ci                                       : raw;
12141cb0ef41Sopenharmony_ci            bool is_self_forwarded =
12151cb0ef41Sopenharmony_ci                forwarded.map_word(cage_base, kRelaxedLoad).ptr() ==
12161cb0ef41Sopenharmony_ci                forwarded.address();
12171cb0ef41Sopenharmony_ci            if (is_self_forwarded) {
12181cb0ef41Sopenharmony_ci              // The object might be in a self-forwarding state if it's located
12191cb0ef41Sopenharmony_ci              // in new large object space. GC will fix this at a later stage.
12201cb0ef41Sopenharmony_ci              CHECK(BasicMemoryChunk::FromHeapObject(forwarded)
12211cb0ef41Sopenharmony_ci                        ->InNewLargeObjectSpace());
12221cb0ef41Sopenharmony_ci            } else {
12231cb0ef41Sopenharmony_ci              CHECK(forwarded.map(cage_base).IsMap(cage_base));
12241cb0ef41Sopenharmony_ci            }
12251cb0ef41Sopenharmony_ci          }
12261cb0ef41Sopenharmony_ci        }
12271cb0ef41Sopenharmony_ci      } else {
12281cb0ef41Sopenharmony_ci        Tagged_t compressed_value =
12291cb0ef41Sopenharmony_ci            static_cast<Tagged_t>(*spill_slot.location());
12301cb0ef41Sopenharmony_ci        if (!HAS_SMI_TAG(compressed_value)) {
12311cb0ef41Sopenharmony_ci          // We don't need to update smi values.
12321cb0ef41Sopenharmony_ci          *spill_slot.location() =
12331cb0ef41Sopenharmony_ci              DecompressTaggedPointer(cage_base, compressed_value);
12341cb0ef41Sopenharmony_ci        }
12351cb0ef41Sopenharmony_ci      }
12361cb0ef41Sopenharmony_ci#endif
12371cb0ef41Sopenharmony_ci      v->VisitRootPointer(Root::kStackRoots, nullptr, spill_slot);
12381cb0ef41Sopenharmony_ci    }
12391cb0ef41Sopenharmony_ci    slot_offset += kBitsPerByte;
12401cb0ef41Sopenharmony_ci  }
12411cb0ef41Sopenharmony_ci
12421cb0ef41Sopenharmony_ci  // Visit tagged parameters that have been passed to the function of this
12431cb0ef41Sopenharmony_ci  // frame. Conceptionally these parameters belong to the parent frame. However,
12441cb0ef41Sopenharmony_ci  // the exact count is only known by this frame (in the presence of tail calls,
12451cb0ef41Sopenharmony_ci  // this information cannot be derived from the call site).
12461cb0ef41Sopenharmony_ci  if (num_tagged_parameter_slots > 0) {
12471cb0ef41Sopenharmony_ci    FullObjectSlot tagged_parameter_base(&Memory<Address>(caller_sp()));
12481cb0ef41Sopenharmony_ci    tagged_parameter_base += first_tagged_parameter_slot;
12491cb0ef41Sopenharmony_ci    FullObjectSlot tagged_parameter_limit =
12501cb0ef41Sopenharmony_ci        tagged_parameter_base + num_tagged_parameter_slots;
12511cb0ef41Sopenharmony_ci
12521cb0ef41Sopenharmony_ci    v->VisitRootPointers(Root::kStackRoots, nullptr, tagged_parameter_base,
12531cb0ef41Sopenharmony_ci                         tagged_parameter_limit);
12541cb0ef41Sopenharmony_ci  }
12551cb0ef41Sopenharmony_ci
12561cb0ef41Sopenharmony_ci  // For the off-heap code cases, we can skip this.
12571cb0ef41Sopenharmony_ci  if (!code.is_null()) {
12581cb0ef41Sopenharmony_ci    // Visit the return address in the callee and incoming arguments.
12591cb0ef41Sopenharmony_ci    IteratePc(v, pc_address(), constant_pool_address(), code);
12601cb0ef41Sopenharmony_ci  }
12611cb0ef41Sopenharmony_ci
12621cb0ef41Sopenharmony_ci  // If this frame has JavaScript ABI, visit the context (in stub and JS
12631cb0ef41Sopenharmony_ci  // frames) and the function (in JS frames). If it has WebAssembly ABI, visit
12641cb0ef41Sopenharmony_ci  // the instance object.
12651cb0ef41Sopenharmony_ci  if (!typed_frame) {
12661cb0ef41Sopenharmony_ci    // JavaScript ABI frames also contain arguments count value which is stored
12671cb0ef41Sopenharmony_ci    // untagged, we don't need to visit it.
12681cb0ef41Sopenharmony_ci    frame_header_base += 1;
12691cb0ef41Sopenharmony_ci  }
12701cb0ef41Sopenharmony_ci  v->VisitRootPointers(Root::kStackRoots, nullptr, frame_header_base,
12711cb0ef41Sopenharmony_ci                       frame_header_limit);
12721cb0ef41Sopenharmony_ci}
12731cb0ef41Sopenharmony_ci
12741cb0ef41Sopenharmony_ciCode StubFrame::unchecked_code() const {
12751cb0ef41Sopenharmony_ci  return isolate()->FindCodeObject(pc());
12761cb0ef41Sopenharmony_ci}
12771cb0ef41Sopenharmony_ci
12781cb0ef41Sopenharmony_ciint StubFrame::LookupExceptionHandlerInTable() {
12791cb0ef41Sopenharmony_ci  Code code = LookupCode();
12801cb0ef41Sopenharmony_ci  DCHECK(code.is_turbofanned());
12811cb0ef41Sopenharmony_ci  DCHECK_EQ(code.kind(), CodeKind::BUILTIN);
12821cb0ef41Sopenharmony_ci  HandlerTable table(code);
12831cb0ef41Sopenharmony_ci  int pc_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
12841cb0ef41Sopenharmony_ci  return table.LookupReturn(pc_offset);
12851cb0ef41Sopenharmony_ci}
12861cb0ef41Sopenharmony_ci
12871cb0ef41Sopenharmony_civoid OptimizedFrame::Iterate(RootVisitor* v) const { IterateCompiledFrame(v); }
12881cb0ef41Sopenharmony_ci
12891cb0ef41Sopenharmony_civoid JavaScriptFrame::SetParameterValue(int index, Object value) const {
12901cb0ef41Sopenharmony_ci  Memory<Address>(GetParameterSlot(index)) = value.ptr();
12911cb0ef41Sopenharmony_ci}
12921cb0ef41Sopenharmony_ci
12931cb0ef41Sopenharmony_cibool JavaScriptFrame::IsConstructor() const {
12941cb0ef41Sopenharmony_ci  return IsConstructFrame(caller_fp());
12951cb0ef41Sopenharmony_ci}
12961cb0ef41Sopenharmony_ci
12971cb0ef41Sopenharmony_cibool JavaScriptFrame::HasInlinedFrames() const {
12981cb0ef41Sopenharmony_ci  std::vector<SharedFunctionInfo> functions;
12991cb0ef41Sopenharmony_ci  GetFunctions(&functions);
13001cb0ef41Sopenharmony_ci  return functions.size() > 1;
13011cb0ef41Sopenharmony_ci}
13021cb0ef41Sopenharmony_ci
13031cb0ef41Sopenharmony_ciCode CommonFrameWithJSLinkage::unchecked_code() const {
13041cb0ef41Sopenharmony_ci  return FromCodeT(function().code());
13051cb0ef41Sopenharmony_ci}
13061cb0ef41Sopenharmony_ci
13071cb0ef41Sopenharmony_ciint OptimizedFrame::ComputeParametersCount() const {
13081cb0ef41Sopenharmony_ci  Code code = LookupCode();
13091cb0ef41Sopenharmony_ci  if (code.kind() == CodeKind::BUILTIN) {
13101cb0ef41Sopenharmony_ci    return static_cast<int>(
13111cb0ef41Sopenharmony_ci               Memory<intptr_t>(fp() + StandardFrameConstants::kArgCOffset)) -
13121cb0ef41Sopenharmony_ci           kJSArgcReceiverSlots;
13131cb0ef41Sopenharmony_ci  } else {
13141cb0ef41Sopenharmony_ci    return JavaScriptFrame::ComputeParametersCount();
13151cb0ef41Sopenharmony_ci  }
13161cb0ef41Sopenharmony_ci}
13171cb0ef41Sopenharmony_ci
13181cb0ef41Sopenharmony_ciAddress JavaScriptFrame::GetCallerStackPointer() const {
13191cb0ef41Sopenharmony_ci  return fp() + StandardFrameConstants::kCallerSPOffset;
13201cb0ef41Sopenharmony_ci}
13211cb0ef41Sopenharmony_ci
13221cb0ef41Sopenharmony_civoid JavaScriptFrame::GetFunctions(
13231cb0ef41Sopenharmony_ci    std::vector<SharedFunctionInfo>* functions) const {
13241cb0ef41Sopenharmony_ci  DCHECK(functions->empty());
13251cb0ef41Sopenharmony_ci  functions->push_back(function().shared());
13261cb0ef41Sopenharmony_ci}
13271cb0ef41Sopenharmony_ci
13281cb0ef41Sopenharmony_civoid JavaScriptFrame::GetFunctions(
13291cb0ef41Sopenharmony_ci    std::vector<Handle<SharedFunctionInfo>>* functions) const {
13301cb0ef41Sopenharmony_ci  DCHECK(functions->empty());
13311cb0ef41Sopenharmony_ci  std::vector<SharedFunctionInfo> raw_functions;
13321cb0ef41Sopenharmony_ci  GetFunctions(&raw_functions);
13331cb0ef41Sopenharmony_ci  for (const auto& raw_function : raw_functions) {
13341cb0ef41Sopenharmony_ci    functions->push_back(
13351cb0ef41Sopenharmony_ci        Handle<SharedFunctionInfo>(raw_function, function().GetIsolate()));
13361cb0ef41Sopenharmony_ci  }
13371cb0ef41Sopenharmony_ci}
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_cibool CommonFrameWithJSLinkage::IsConstructor() const {
13401cb0ef41Sopenharmony_ci  return IsConstructFrame(caller_fp());
13411cb0ef41Sopenharmony_ci}
13421cb0ef41Sopenharmony_ci
13431cb0ef41Sopenharmony_civoid CommonFrameWithJSLinkage::Summarize(
13441cb0ef41Sopenharmony_ci    std::vector<FrameSummary>* functions) const {
13451cb0ef41Sopenharmony_ci  DCHECK(functions->empty());
13461cb0ef41Sopenharmony_ci  Code code = LookupCode();
13471cb0ef41Sopenharmony_ci  int offset = code.GetOffsetFromInstructionStart(isolate(), pc());
13481cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code(AbstractCode::cast(code), isolate());
13491cb0ef41Sopenharmony_ci  Handle<FixedArray> params = GetParameters();
13501cb0ef41Sopenharmony_ci  FrameSummary::JavaScriptFrameSummary summary(
13511cb0ef41Sopenharmony_ci      isolate(), receiver(), function(), *abstract_code, offset,
13521cb0ef41Sopenharmony_ci      IsConstructor(), *params);
13531cb0ef41Sopenharmony_ci  functions->push_back(summary);
13541cb0ef41Sopenharmony_ci}
13551cb0ef41Sopenharmony_ci
13561cb0ef41Sopenharmony_ciJSFunction JavaScriptFrame::function() const {
13571cb0ef41Sopenharmony_ci  return JSFunction::cast(function_slot_object());
13581cb0ef41Sopenharmony_ci}
13591cb0ef41Sopenharmony_ci
13601cb0ef41Sopenharmony_ciObject JavaScriptFrame::unchecked_function() const {
13611cb0ef41Sopenharmony_ci  // During deoptimization of an optimized function, we may have yet to
13621cb0ef41Sopenharmony_ci  // materialize some closures on the stack. The arguments marker object
13631cb0ef41Sopenharmony_ci  // marks this case.
13641cb0ef41Sopenharmony_ci  DCHECK(function_slot_object().IsJSFunction() ||
13651cb0ef41Sopenharmony_ci         ReadOnlyRoots(isolate()).arguments_marker() == function_slot_object());
13661cb0ef41Sopenharmony_ci  return function_slot_object();
13671cb0ef41Sopenharmony_ci}
13681cb0ef41Sopenharmony_ci
13691cb0ef41Sopenharmony_ciObject CommonFrameWithJSLinkage::receiver() const { return GetParameter(-1); }
13701cb0ef41Sopenharmony_ci
13711cb0ef41Sopenharmony_ciObject JavaScriptFrame::context() const {
13721cb0ef41Sopenharmony_ci  const int offset = StandardFrameConstants::kContextOffset;
13731cb0ef41Sopenharmony_ci  Object maybe_result(Memory<Address>(fp() + offset));
13741cb0ef41Sopenharmony_ci  DCHECK(!maybe_result.IsSmi());
13751cb0ef41Sopenharmony_ci  return maybe_result;
13761cb0ef41Sopenharmony_ci}
13771cb0ef41Sopenharmony_ci
13781cb0ef41Sopenharmony_ciScript JavaScriptFrame::script() const {
13791cb0ef41Sopenharmony_ci  return Script::cast(function().shared().script());
13801cb0ef41Sopenharmony_ci}
13811cb0ef41Sopenharmony_ci
13821cb0ef41Sopenharmony_ciint CommonFrameWithJSLinkage::LookupExceptionHandlerInTable(
13831cb0ef41Sopenharmony_ci    int* stack_depth, HandlerTable::CatchPrediction* prediction) {
13841cb0ef41Sopenharmony_ci  DCHECK(!LookupCode().has_handler_table());
13851cb0ef41Sopenharmony_ci  DCHECK(!LookupCode().is_optimized_code() ||
13861cb0ef41Sopenharmony_ci         LookupCode().kind() == CodeKind::BASELINE);
13871cb0ef41Sopenharmony_ci  return -1;
13881cb0ef41Sopenharmony_ci}
13891cb0ef41Sopenharmony_ci
13901cb0ef41Sopenharmony_civoid JavaScriptFrame::PrintFunctionAndOffset(JSFunction function,
13911cb0ef41Sopenharmony_ci                                             AbstractCode code, int code_offset,
13921cb0ef41Sopenharmony_ci                                             FILE* file,
13931cb0ef41Sopenharmony_ci                                             bool print_line_number) {
13941cb0ef41Sopenharmony_ci  PrintF(file, "%s", CodeKindToMarker(code.kind()));
13951cb0ef41Sopenharmony_ci  function.PrintName(file);
13961cb0ef41Sopenharmony_ci  PrintF(file, "+%d", code_offset);
13971cb0ef41Sopenharmony_ci  if (print_line_number) {
13981cb0ef41Sopenharmony_ci    SharedFunctionInfo shared = function.shared();
13991cb0ef41Sopenharmony_ci    int source_pos = code.SourcePosition(code_offset);
14001cb0ef41Sopenharmony_ci    Object maybe_script = shared.script();
14011cb0ef41Sopenharmony_ci    if (maybe_script.IsScript()) {
14021cb0ef41Sopenharmony_ci      Script script = Script::cast(maybe_script);
14031cb0ef41Sopenharmony_ci      int line = script.GetLineNumber(source_pos) + 1;
14041cb0ef41Sopenharmony_ci      Object script_name_raw = script.name();
14051cb0ef41Sopenharmony_ci      if (script_name_raw.IsString()) {
14061cb0ef41Sopenharmony_ci        String script_name = String::cast(script.name());
14071cb0ef41Sopenharmony_ci        std::unique_ptr<char[]> c_script_name =
14081cb0ef41Sopenharmony_ci            script_name.ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
14091cb0ef41Sopenharmony_ci        PrintF(file, " at %s:%d", c_script_name.get(), line);
14101cb0ef41Sopenharmony_ci      } else {
14111cb0ef41Sopenharmony_ci        PrintF(file, " at <unknown>:%d", line);
14121cb0ef41Sopenharmony_ci      }
14131cb0ef41Sopenharmony_ci    } else {
14141cb0ef41Sopenharmony_ci      PrintF(file, " at <unknown>:<unknown>");
14151cb0ef41Sopenharmony_ci    }
14161cb0ef41Sopenharmony_ci  }
14171cb0ef41Sopenharmony_ci}
14181cb0ef41Sopenharmony_ci
14191cb0ef41Sopenharmony_civoid JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
14201cb0ef41Sopenharmony_ci                               bool print_line_number) {
14211cb0ef41Sopenharmony_ci  // constructor calls
14221cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
14231cb0ef41Sopenharmony_ci  JavaScriptFrameIterator it(isolate);
14241cb0ef41Sopenharmony_ci  while (!it.done()) {
14251cb0ef41Sopenharmony_ci    if (it.frame()->is_java_script()) {
14261cb0ef41Sopenharmony_ci      JavaScriptFrame* frame = it.frame();
14271cb0ef41Sopenharmony_ci      if (frame->IsConstructor()) PrintF(file, "new ");
14281cb0ef41Sopenharmony_ci      JSFunction function = frame->function();
14291cb0ef41Sopenharmony_ci      int code_offset = 0;
14301cb0ef41Sopenharmony_ci      AbstractCode abstract_code = function.abstract_code(isolate);
14311cb0ef41Sopenharmony_ci      if (frame->is_interpreted()) {
14321cb0ef41Sopenharmony_ci        InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame);
14331cb0ef41Sopenharmony_ci        code_offset = iframe->GetBytecodeOffset();
14341cb0ef41Sopenharmony_ci      } else if (frame->is_baseline()) {
14351cb0ef41Sopenharmony_ci        // TODO(pthier): AbstractCode should fully support Baseline code.
14361cb0ef41Sopenharmony_ci        BaselineFrame* baseline_frame = BaselineFrame::cast(frame);
14371cb0ef41Sopenharmony_ci        code_offset = baseline_frame->GetBytecodeOffset();
14381cb0ef41Sopenharmony_ci        abstract_code = AbstractCode::cast(baseline_frame->GetBytecodeArray());
14391cb0ef41Sopenharmony_ci      } else {
14401cb0ef41Sopenharmony_ci        Code code = frame->unchecked_code();
14411cb0ef41Sopenharmony_ci        code_offset = code.GetOffsetFromInstructionStart(isolate, frame->pc());
14421cb0ef41Sopenharmony_ci      }
14431cb0ef41Sopenharmony_ci      PrintFunctionAndOffset(function, abstract_code, code_offset, file,
14441cb0ef41Sopenharmony_ci                             print_line_number);
14451cb0ef41Sopenharmony_ci      if (print_args) {
14461cb0ef41Sopenharmony_ci        // function arguments
14471cb0ef41Sopenharmony_ci        // (we are intentionally only printing the actually
14481cb0ef41Sopenharmony_ci        // supplied parameters, not all parameters required)
14491cb0ef41Sopenharmony_ci        PrintF(file, "(this=");
14501cb0ef41Sopenharmony_ci        frame->receiver().ShortPrint(file);
14511cb0ef41Sopenharmony_ci        const int length = frame->ComputeParametersCount();
14521cb0ef41Sopenharmony_ci        for (int i = 0; i < length; i++) {
14531cb0ef41Sopenharmony_ci          PrintF(file, ", ");
14541cb0ef41Sopenharmony_ci          frame->GetParameter(i).ShortPrint(file);
14551cb0ef41Sopenharmony_ci        }
14561cb0ef41Sopenharmony_ci        PrintF(file, ")");
14571cb0ef41Sopenharmony_ci      }
14581cb0ef41Sopenharmony_ci      break;
14591cb0ef41Sopenharmony_ci    }
14601cb0ef41Sopenharmony_ci    it.Advance();
14611cb0ef41Sopenharmony_ci  }
14621cb0ef41Sopenharmony_ci}
14631cb0ef41Sopenharmony_ci
14641cb0ef41Sopenharmony_civoid JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction function,
14651cb0ef41Sopenharmony_ci                                                         AbstractCode code,
14661cb0ef41Sopenharmony_ci                                                         int code_offset) {
14671cb0ef41Sopenharmony_ci  auto ic_stats = ICStats::instance();
14681cb0ef41Sopenharmony_ci  ICInfo& ic_info = ic_stats->Current();
14691cb0ef41Sopenharmony_ci  SharedFunctionInfo shared = function.shared();
14701cb0ef41Sopenharmony_ci
14711cb0ef41Sopenharmony_ci  ic_info.function_name = ic_stats->GetOrCacheFunctionName(function);
14721cb0ef41Sopenharmony_ci  ic_info.script_offset = code_offset;
14731cb0ef41Sopenharmony_ci
14741cb0ef41Sopenharmony_ci  int source_pos = code.SourcePosition(code_offset);
14751cb0ef41Sopenharmony_ci  Object maybe_script = shared.script();
14761cb0ef41Sopenharmony_ci  if (maybe_script.IsScript()) {
14771cb0ef41Sopenharmony_ci    Script script = Script::cast(maybe_script);
14781cb0ef41Sopenharmony_ci    ic_info.line_num = script.GetLineNumber(source_pos) + 1;
14791cb0ef41Sopenharmony_ci    ic_info.column_num = script.GetColumnNumber(source_pos);
14801cb0ef41Sopenharmony_ci    ic_info.script_name = ic_stats->GetOrCacheScriptName(script);
14811cb0ef41Sopenharmony_ci  }
14821cb0ef41Sopenharmony_ci}
14831cb0ef41Sopenharmony_ci
14841cb0ef41Sopenharmony_ciObject CommonFrameWithJSLinkage::GetParameter(int index) const {
14851cb0ef41Sopenharmony_ci  return Object(Memory<Address>(GetParameterSlot(index)));
14861cb0ef41Sopenharmony_ci}
14871cb0ef41Sopenharmony_ci
14881cb0ef41Sopenharmony_ciint CommonFrameWithJSLinkage::ComputeParametersCount() const {
14891cb0ef41Sopenharmony_ci  DCHECK(can_access_heap_objects() &&
14901cb0ef41Sopenharmony_ci         isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
14911cb0ef41Sopenharmony_ci  return function().shared().internal_formal_parameter_count_without_receiver();
14921cb0ef41Sopenharmony_ci}
14931cb0ef41Sopenharmony_ci
14941cb0ef41Sopenharmony_ciint JavaScriptFrame::GetActualArgumentCount() const {
14951cb0ef41Sopenharmony_ci  return static_cast<int>(
14961cb0ef41Sopenharmony_ci             Memory<intptr_t>(fp() + StandardFrameConstants::kArgCOffset)) -
14971cb0ef41Sopenharmony_ci         kJSArgcReceiverSlots;
14981cb0ef41Sopenharmony_ci}
14991cb0ef41Sopenharmony_ci
15001cb0ef41Sopenharmony_ciHandle<FixedArray> CommonFrameWithJSLinkage::GetParameters() const {
15011cb0ef41Sopenharmony_ci  if (V8_LIKELY(!FLAG_detailed_error_stack_trace)) {
15021cb0ef41Sopenharmony_ci    return isolate()->factory()->empty_fixed_array();
15031cb0ef41Sopenharmony_ci  }
15041cb0ef41Sopenharmony_ci  int param_count = ComputeParametersCount();
15051cb0ef41Sopenharmony_ci  Handle<FixedArray> parameters =
15061cb0ef41Sopenharmony_ci      isolate()->factory()->NewFixedArray(param_count);
15071cb0ef41Sopenharmony_ci  for (int i = 0; i < param_count; i++) {
15081cb0ef41Sopenharmony_ci    parameters->set(i, GetParameter(i));
15091cb0ef41Sopenharmony_ci  }
15101cb0ef41Sopenharmony_ci
15111cb0ef41Sopenharmony_ci  return parameters;
15121cb0ef41Sopenharmony_ci}
15131cb0ef41Sopenharmony_ci
15141cb0ef41Sopenharmony_ciJSFunction JavaScriptBuiltinContinuationFrame::function() const {
15151cb0ef41Sopenharmony_ci  const int offset = BuiltinContinuationFrameConstants::kFunctionOffset;
15161cb0ef41Sopenharmony_ci  return JSFunction::cast(Object(base::Memory<Address>(fp() + offset)));
15171cb0ef41Sopenharmony_ci}
15181cb0ef41Sopenharmony_ci
15191cb0ef41Sopenharmony_ciint JavaScriptBuiltinContinuationFrame::ComputeParametersCount() const {
15201cb0ef41Sopenharmony_ci  // Assert that the first allocatable register is also the argument count
15211cb0ef41Sopenharmony_ci  // register.
15221cb0ef41Sopenharmony_ci  DCHECK_EQ(RegisterConfiguration::Default()->GetAllocatableGeneralCode(0),
15231cb0ef41Sopenharmony_ci            kJavaScriptCallArgCountRegister.code());
15241cb0ef41Sopenharmony_ci  Object argc_object(
15251cb0ef41Sopenharmony_ci      Memory<Address>(fp() + BuiltinContinuationFrameConstants::kArgCOffset));
15261cb0ef41Sopenharmony_ci  return Smi::ToInt(argc_object) - kJSArgcReceiverSlots;
15271cb0ef41Sopenharmony_ci}
15281cb0ef41Sopenharmony_ci
15291cb0ef41Sopenharmony_ciintptr_t JavaScriptBuiltinContinuationFrame::GetSPToFPDelta() const {
15301cb0ef41Sopenharmony_ci  Address height_slot =
15311cb0ef41Sopenharmony_ci      fp() + BuiltinContinuationFrameConstants::kFrameSPtoFPDeltaAtDeoptimize;
15321cb0ef41Sopenharmony_ci  intptr_t height = Smi::ToInt(Smi(Memory<Address>(height_slot)));
15331cb0ef41Sopenharmony_ci  return height;
15341cb0ef41Sopenharmony_ci}
15351cb0ef41Sopenharmony_ci
15361cb0ef41Sopenharmony_ciObject JavaScriptBuiltinContinuationFrame::context() const {
15371cb0ef41Sopenharmony_ci  return Object(Memory<Address>(
15381cb0ef41Sopenharmony_ci      fp() + BuiltinContinuationFrameConstants::kBuiltinContextOffset));
15391cb0ef41Sopenharmony_ci}
15401cb0ef41Sopenharmony_ci
15411cb0ef41Sopenharmony_civoid JavaScriptBuiltinContinuationWithCatchFrame::SetException(
15421cb0ef41Sopenharmony_ci    Object exception) {
15431cb0ef41Sopenharmony_ci  int argc = ComputeParametersCount();
15441cb0ef41Sopenharmony_ci  Address exception_argument_slot =
15451cb0ef41Sopenharmony_ci      fp() + BuiltinContinuationFrameConstants::kFixedFrameSizeAboveFp +
15461cb0ef41Sopenharmony_ci      (argc - 1) * kSystemPointerSize;
15471cb0ef41Sopenharmony_ci
15481cb0ef41Sopenharmony_ci  // Only allow setting exception if previous value was the hole.
15491cb0ef41Sopenharmony_ci  CHECK_EQ(ReadOnlyRoots(isolate()).the_hole_value(),
15501cb0ef41Sopenharmony_ci           Object(Memory<Address>(exception_argument_slot)));
15511cb0ef41Sopenharmony_ci  Memory<Address>(exception_argument_slot) = exception.ptr();
15521cb0ef41Sopenharmony_ci}
15531cb0ef41Sopenharmony_ci
15541cb0ef41Sopenharmony_ciFrameSummary::JavaScriptFrameSummary::JavaScriptFrameSummary(
15551cb0ef41Sopenharmony_ci    Isolate* isolate, Object receiver, JSFunction function,
15561cb0ef41Sopenharmony_ci    AbstractCode abstract_code, int code_offset, bool is_constructor,
15571cb0ef41Sopenharmony_ci    FixedArray parameters)
15581cb0ef41Sopenharmony_ci    : FrameSummaryBase(isolate, FrameSummary::JAVA_SCRIPT),
15591cb0ef41Sopenharmony_ci      receiver_(receiver, isolate),
15601cb0ef41Sopenharmony_ci      function_(function, isolate),
15611cb0ef41Sopenharmony_ci      abstract_code_(abstract_code, isolate),
15621cb0ef41Sopenharmony_ci      code_offset_(code_offset),
15631cb0ef41Sopenharmony_ci      is_constructor_(is_constructor),
15641cb0ef41Sopenharmony_ci      parameters_(parameters, isolate) {
15651cb0ef41Sopenharmony_ci  DCHECK(abstract_code.IsBytecodeArray() ||
15661cb0ef41Sopenharmony_ci         !CodeKindIsOptimizedJSFunction(Code::cast(abstract_code).kind()));
15671cb0ef41Sopenharmony_ci}
15681cb0ef41Sopenharmony_ci
15691cb0ef41Sopenharmony_civoid FrameSummary::EnsureSourcePositionsAvailable() {
15701cb0ef41Sopenharmony_ci  if (IsJavaScript()) {
15711cb0ef41Sopenharmony_ci    java_script_summary_.EnsureSourcePositionsAvailable();
15721cb0ef41Sopenharmony_ci  }
15731cb0ef41Sopenharmony_ci}
15741cb0ef41Sopenharmony_ci
15751cb0ef41Sopenharmony_cibool FrameSummary::AreSourcePositionsAvailable() const {
15761cb0ef41Sopenharmony_ci  if (IsJavaScript()) {
15771cb0ef41Sopenharmony_ci    return java_script_summary_.AreSourcePositionsAvailable();
15781cb0ef41Sopenharmony_ci  }
15791cb0ef41Sopenharmony_ci  return true;
15801cb0ef41Sopenharmony_ci}
15811cb0ef41Sopenharmony_ci
15821cb0ef41Sopenharmony_civoid FrameSummary::JavaScriptFrameSummary::EnsureSourcePositionsAvailable() {
15831cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function()->shared(), isolate());
15841cb0ef41Sopenharmony_ci  SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate(), shared);
15851cb0ef41Sopenharmony_ci}
15861cb0ef41Sopenharmony_ci
15871cb0ef41Sopenharmony_cibool FrameSummary::JavaScriptFrameSummary::AreSourcePositionsAvailable() const {
15881cb0ef41Sopenharmony_ci  return !FLAG_enable_lazy_source_positions || function()
15891cb0ef41Sopenharmony_ci                                                   ->shared()
15901cb0ef41Sopenharmony_ci                                                   .GetBytecodeArray(isolate())
15911cb0ef41Sopenharmony_ci                                                   .HasSourcePositionTable();
15921cb0ef41Sopenharmony_ci}
15931cb0ef41Sopenharmony_ci
15941cb0ef41Sopenharmony_cibool FrameSummary::JavaScriptFrameSummary::is_subject_to_debugging() const {
15951cb0ef41Sopenharmony_ci  return function()->shared().IsSubjectToDebugging();
15961cb0ef41Sopenharmony_ci}
15971cb0ef41Sopenharmony_ci
15981cb0ef41Sopenharmony_ciint FrameSummary::JavaScriptFrameSummary::SourcePosition() const {
15991cb0ef41Sopenharmony_ci  return abstract_code()->SourcePosition(code_offset());
16001cb0ef41Sopenharmony_ci}
16011cb0ef41Sopenharmony_ci
16021cb0ef41Sopenharmony_ciint FrameSummary::JavaScriptFrameSummary::SourceStatementPosition() const {
16031cb0ef41Sopenharmony_ci  return abstract_code()->SourceStatementPosition(code_offset());
16041cb0ef41Sopenharmony_ci}
16051cb0ef41Sopenharmony_ci
16061cb0ef41Sopenharmony_ciHandle<Object> FrameSummary::JavaScriptFrameSummary::script() const {
16071cb0ef41Sopenharmony_ci  return handle(function_->shared().script(), isolate());
16081cb0ef41Sopenharmony_ci}
16091cb0ef41Sopenharmony_ci
16101cb0ef41Sopenharmony_ciHandle<Context> FrameSummary::JavaScriptFrameSummary::native_context() const {
16111cb0ef41Sopenharmony_ci  return handle(function_->native_context(), isolate());
16121cb0ef41Sopenharmony_ci}
16131cb0ef41Sopenharmony_ci
16141cb0ef41Sopenharmony_ciHandle<StackFrameInfo>
16151cb0ef41Sopenharmony_ciFrameSummary::JavaScriptFrameSummary::CreateStackFrameInfo() const {
16161cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared(function_->shared(), isolate());
16171cb0ef41Sopenharmony_ci  Handle<Script> script(Script::cast(shared->script()), isolate());
16181cb0ef41Sopenharmony_ci  Handle<String> function_name = JSFunction::GetDebugName(function_);
16191cb0ef41Sopenharmony_ci  if (function_name->length() == 0 &&
16201cb0ef41Sopenharmony_ci      script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
16211cb0ef41Sopenharmony_ci    function_name = isolate()->factory()->eval_string();
16221cb0ef41Sopenharmony_ci  }
16231cb0ef41Sopenharmony_ci  int bytecode_offset = code_offset();
16241cb0ef41Sopenharmony_ci  if (bytecode_offset == kFunctionEntryBytecodeOffset) {
16251cb0ef41Sopenharmony_ci    // For the special function entry bytecode offset (-1), which signals
16261cb0ef41Sopenharmony_ci    // that the stack trace was captured while the function entry was
16271cb0ef41Sopenharmony_ci    // executing (i.e. during the interrupt check), we cannot store this
16281cb0ef41Sopenharmony_ci    // sentinel in the bit field, so we just eagerly lookup the source
16291cb0ef41Sopenharmony_ci    // position within the script.
16301cb0ef41Sopenharmony_ci    SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate(), shared);
16311cb0ef41Sopenharmony_ci    int source_position = abstract_code()->SourcePosition(bytecode_offset);
16321cb0ef41Sopenharmony_ci    return isolate()->factory()->NewStackFrameInfo(
16331cb0ef41Sopenharmony_ci        script, source_position, function_name, is_constructor());
16341cb0ef41Sopenharmony_ci  }
16351cb0ef41Sopenharmony_ci  return isolate()->factory()->NewStackFrameInfo(
16361cb0ef41Sopenharmony_ci      shared, bytecode_offset, function_name, is_constructor());
16371cb0ef41Sopenharmony_ci}
16381cb0ef41Sopenharmony_ci
16391cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
16401cb0ef41Sopenharmony_ciFrameSummary::WasmFrameSummary::WasmFrameSummary(
16411cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<WasmInstanceObject> instance, wasm::WasmCode* code,
16421cb0ef41Sopenharmony_ci    int code_offset, bool at_to_number_conversion)
16431cb0ef41Sopenharmony_ci    : FrameSummaryBase(isolate, WASM),
16441cb0ef41Sopenharmony_ci      wasm_instance_(instance),
16451cb0ef41Sopenharmony_ci      at_to_number_conversion_(at_to_number_conversion),
16461cb0ef41Sopenharmony_ci      code_(code),
16471cb0ef41Sopenharmony_ci      code_offset_(code_offset) {}
16481cb0ef41Sopenharmony_ci
16491cb0ef41Sopenharmony_ciHandle<Object> FrameSummary::WasmFrameSummary::receiver() const {
16501cb0ef41Sopenharmony_ci  return wasm_instance_->GetIsolate()->global_proxy();
16511cb0ef41Sopenharmony_ci}
16521cb0ef41Sopenharmony_ci
16531cb0ef41Sopenharmony_ciuint32_t FrameSummary::WasmFrameSummary::function_index() const {
16541cb0ef41Sopenharmony_ci  return code()->index();
16551cb0ef41Sopenharmony_ci}
16561cb0ef41Sopenharmony_ci
16571cb0ef41Sopenharmony_ciint FrameSummary::WasmFrameSummary::byte_offset() const {
16581cb0ef41Sopenharmony_ci  return code_->GetSourcePositionBefore(code_offset());
16591cb0ef41Sopenharmony_ci}
16601cb0ef41Sopenharmony_ci
16611cb0ef41Sopenharmony_ciint FrameSummary::WasmFrameSummary::SourcePosition() const {
16621cb0ef41Sopenharmony_ci  const wasm::WasmModule* module = wasm_instance()->module_object().module();
16631cb0ef41Sopenharmony_ci  return GetSourcePosition(module, function_index(), byte_offset(),
16641cb0ef41Sopenharmony_ci                           at_to_number_conversion());
16651cb0ef41Sopenharmony_ci}
16661cb0ef41Sopenharmony_ci
16671cb0ef41Sopenharmony_ciHandle<Script> FrameSummary::WasmFrameSummary::script() const {
16681cb0ef41Sopenharmony_ci  return handle(wasm_instance()->module_object().script(),
16691cb0ef41Sopenharmony_ci                wasm_instance()->GetIsolate());
16701cb0ef41Sopenharmony_ci}
16711cb0ef41Sopenharmony_ci
16721cb0ef41Sopenharmony_ciHandle<Context> FrameSummary::WasmFrameSummary::native_context() const {
16731cb0ef41Sopenharmony_ci  return handle(wasm_instance()->native_context(), isolate());
16741cb0ef41Sopenharmony_ci}
16751cb0ef41Sopenharmony_ci
16761cb0ef41Sopenharmony_ciHandle<StackFrameInfo> FrameSummary::WasmFrameSummary::CreateStackFrameInfo()
16771cb0ef41Sopenharmony_ci    const {
16781cb0ef41Sopenharmony_ci  Handle<String> function_name =
16791cb0ef41Sopenharmony_ci      GetWasmFunctionDebugName(isolate(), wasm_instance(), function_index());
16801cb0ef41Sopenharmony_ci  return isolate()->factory()->NewStackFrameInfo(script(), SourcePosition(),
16811cb0ef41Sopenharmony_ci                                                 function_name, false);
16821cb0ef41Sopenharmony_ci}
16831cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
16841cb0ef41Sopenharmony_ci
16851cb0ef41Sopenharmony_ciFrameSummary::~FrameSummary() {
16861cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_DESTR(kind, type, field, desc) \
16871cb0ef41Sopenharmony_ci  case kind:                                         \
16881cb0ef41Sopenharmony_ci    field.~type();                                   \
16891cb0ef41Sopenharmony_ci    break;
16901cb0ef41Sopenharmony_ci  switch (base_.kind()) {
16911cb0ef41Sopenharmony_ci    FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_DESTR)
16921cb0ef41Sopenharmony_ci    default:
16931cb0ef41Sopenharmony_ci      UNREACHABLE();
16941cb0ef41Sopenharmony_ci  }
16951cb0ef41Sopenharmony_ci#undef FRAME_SUMMARY_DESTR
16961cb0ef41Sopenharmony_ci}
16971cb0ef41Sopenharmony_ci
16981cb0ef41Sopenharmony_ciFrameSummary FrameSummary::GetTop(const CommonFrame* frame) {
16991cb0ef41Sopenharmony_ci  std::vector<FrameSummary> frames;
17001cb0ef41Sopenharmony_ci  frame->Summarize(&frames);
17011cb0ef41Sopenharmony_ci  DCHECK_LT(0, frames.size());
17021cb0ef41Sopenharmony_ci  return frames.back();
17031cb0ef41Sopenharmony_ci}
17041cb0ef41Sopenharmony_ci
17051cb0ef41Sopenharmony_ciFrameSummary FrameSummary::GetBottom(const CommonFrame* frame) {
17061cb0ef41Sopenharmony_ci  return Get(frame, 0);
17071cb0ef41Sopenharmony_ci}
17081cb0ef41Sopenharmony_ci
17091cb0ef41Sopenharmony_ciFrameSummary FrameSummary::GetSingle(const CommonFrame* frame) {
17101cb0ef41Sopenharmony_ci  std::vector<FrameSummary> frames;
17111cb0ef41Sopenharmony_ci  frame->Summarize(&frames);
17121cb0ef41Sopenharmony_ci  DCHECK_EQ(1, frames.size());
17131cb0ef41Sopenharmony_ci  return frames.front();
17141cb0ef41Sopenharmony_ci}
17151cb0ef41Sopenharmony_ci
17161cb0ef41Sopenharmony_ciFrameSummary FrameSummary::Get(const CommonFrame* frame, int index) {
17171cb0ef41Sopenharmony_ci  DCHECK_LE(0, index);
17181cb0ef41Sopenharmony_ci  std::vector<FrameSummary> frames;
17191cb0ef41Sopenharmony_ci  frame->Summarize(&frames);
17201cb0ef41Sopenharmony_ci  DCHECK_GT(frames.size(), index);
17211cb0ef41Sopenharmony_ci  return frames[index];
17221cb0ef41Sopenharmony_ci}
17231cb0ef41Sopenharmony_ci
17241cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
17251cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_DISPATCH(ret, name)   \
17261cb0ef41Sopenharmony_ci  ret FrameSummary::name() const {          \
17271cb0ef41Sopenharmony_ci    switch (base_.kind()) {                 \
17281cb0ef41Sopenharmony_ci      case JAVA_SCRIPT:                     \
17291cb0ef41Sopenharmony_ci        return java_script_summary_.name(); \
17301cb0ef41Sopenharmony_ci      case WASM:                            \
17311cb0ef41Sopenharmony_ci        return wasm_summary_.name();        \
17321cb0ef41Sopenharmony_ci      default:                              \
17331cb0ef41Sopenharmony_ci        UNREACHABLE();                      \
17341cb0ef41Sopenharmony_ci    }                                       \
17351cb0ef41Sopenharmony_ci  }
17361cb0ef41Sopenharmony_ci#else
17371cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_DISPATCH(ret, name) \
17381cb0ef41Sopenharmony_ci  ret FrameSummary::name() const {        \
17391cb0ef41Sopenharmony_ci    DCHECK_EQ(JAVA_SCRIPT, base_.kind()); \
17401cb0ef41Sopenharmony_ci    return java_script_summary_.name();   \
17411cb0ef41Sopenharmony_ci  }
17421cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
17431cb0ef41Sopenharmony_ci
17441cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(Handle<Object>, receiver)
17451cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(int, code_offset)
17461cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(bool, is_constructor)
17471cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(bool, is_subject_to_debugging)
17481cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(Handle<Object>, script)
17491cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(int, SourcePosition)
17501cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(int, SourceStatementPosition)
17511cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(Handle<Context>, native_context)
17521cb0ef41Sopenharmony_ciFRAME_SUMMARY_DISPATCH(Handle<StackFrameInfo>, CreateStackFrameInfo)
17531cb0ef41Sopenharmony_ci
17541cb0ef41Sopenharmony_ci#undef FRAME_SUMMARY_DISPATCH
17551cb0ef41Sopenharmony_ci
17561cb0ef41Sopenharmony_civoid OptimizedFrame::Summarize(std::vector<FrameSummary>* frames) const {
17571cb0ef41Sopenharmony_ci  DCHECK(frames->empty());
17581cb0ef41Sopenharmony_ci  DCHECK(is_optimized());
17591cb0ef41Sopenharmony_ci
17601cb0ef41Sopenharmony_ci  // Delegate to JS frame in absence of turbofan deoptimization.
17611cb0ef41Sopenharmony_ci  // TODO(turbofan): Revisit once we support deoptimization across the board.
17621cb0ef41Sopenharmony_ci  Code code = LookupCode();
17631cb0ef41Sopenharmony_ci  if (code.kind() == CodeKind::BUILTIN) {
17641cb0ef41Sopenharmony_ci    return JavaScriptFrame::Summarize(frames);
17651cb0ef41Sopenharmony_ci  }
17661cb0ef41Sopenharmony_ci
17671cb0ef41Sopenharmony_ci  int deopt_index = SafepointEntry::kNoDeoptIndex;
17681cb0ef41Sopenharmony_ci  DeoptimizationData const data = GetDeoptimizationData(&deopt_index);
17691cb0ef41Sopenharmony_ci  if (deopt_index == SafepointEntry::kNoDeoptIndex) {
17701cb0ef41Sopenharmony_ci    CHECK(data.is_null());
17711cb0ef41Sopenharmony_ci    FATAL("Missing deoptimization information for OptimizedFrame::Summarize.");
17721cb0ef41Sopenharmony_ci  }
17731cb0ef41Sopenharmony_ci
17741cb0ef41Sopenharmony_ci  // Prepare iteration over translation. Note that the below iteration might
17751cb0ef41Sopenharmony_ci  // materialize objects without storing them back to the Isolate, this will
17761cb0ef41Sopenharmony_ci  // lead to objects being re-materialized again for each summary.
17771cb0ef41Sopenharmony_ci  TranslatedState translated(this);
17781cb0ef41Sopenharmony_ci  translated.Prepare(fp());
17791cb0ef41Sopenharmony_ci
17801cb0ef41Sopenharmony_ci  // We create the summary in reverse order because the frames
17811cb0ef41Sopenharmony_ci  // in the deoptimization translation are ordered bottom-to-top.
17821cb0ef41Sopenharmony_ci  bool is_constructor = IsConstructor();
17831cb0ef41Sopenharmony_ci  for (auto it = translated.begin(); it != translated.end(); it++) {
17841cb0ef41Sopenharmony_ci    if (it->kind() == TranslatedFrame::kUnoptimizedFunction ||
17851cb0ef41Sopenharmony_ci        it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation ||
17861cb0ef41Sopenharmony_ci        it->kind() ==
17871cb0ef41Sopenharmony_ci            TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch) {
17881cb0ef41Sopenharmony_ci      Handle<SharedFunctionInfo> shared_info = it->shared_info();
17891cb0ef41Sopenharmony_ci
17901cb0ef41Sopenharmony_ci      // The translation commands are ordered and the function is always
17911cb0ef41Sopenharmony_ci      // at the first position, and the receiver is next.
17921cb0ef41Sopenharmony_ci      TranslatedFrame::iterator translated_values = it->begin();
17931cb0ef41Sopenharmony_ci
17941cb0ef41Sopenharmony_ci      // Get or materialize the correct function in the optimized frame.
17951cb0ef41Sopenharmony_ci      Handle<JSFunction> function =
17961cb0ef41Sopenharmony_ci          Handle<JSFunction>::cast(translated_values->GetValue());
17971cb0ef41Sopenharmony_ci      translated_values++;
17981cb0ef41Sopenharmony_ci
17991cb0ef41Sopenharmony_ci      // Get or materialize the correct receiver in the optimized frame.
18001cb0ef41Sopenharmony_ci      Handle<Object> receiver = translated_values->GetValue();
18011cb0ef41Sopenharmony_ci      translated_values++;
18021cb0ef41Sopenharmony_ci
18031cb0ef41Sopenharmony_ci      // Determine the underlying code object and the position within it from
18041cb0ef41Sopenharmony_ci      // the translation corresponding to the frame type in question.
18051cb0ef41Sopenharmony_ci      Handle<AbstractCode> abstract_code;
18061cb0ef41Sopenharmony_ci      unsigned code_offset;
18071cb0ef41Sopenharmony_ci      if (it->kind() == TranslatedFrame::kJavaScriptBuiltinContinuation ||
18081cb0ef41Sopenharmony_ci          it->kind() ==
18091cb0ef41Sopenharmony_ci              TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch) {
18101cb0ef41Sopenharmony_ci        code_offset = 0;
18111cb0ef41Sopenharmony_ci        abstract_code = ToAbstractCode(
18121cb0ef41Sopenharmony_ci            isolate()->builtins()->code_handle(
18131cb0ef41Sopenharmony_ci                Builtins::GetBuiltinFromBytecodeOffset(it->bytecode_offset())),
18141cb0ef41Sopenharmony_ci            isolate());
18151cb0ef41Sopenharmony_ci      } else {
18161cb0ef41Sopenharmony_ci        DCHECK_EQ(it->kind(), TranslatedFrame::kUnoptimizedFunction);
18171cb0ef41Sopenharmony_ci        code_offset = it->bytecode_offset().ToInt();
18181cb0ef41Sopenharmony_ci        abstract_code =
18191cb0ef41Sopenharmony_ci            handle(shared_info->abstract_code(isolate()), isolate());
18201cb0ef41Sopenharmony_ci      }
18211cb0ef41Sopenharmony_ci
18221cb0ef41Sopenharmony_ci      // Append full summary of the encountered JS frame.
18231cb0ef41Sopenharmony_ci      Handle<FixedArray> params = GetParameters();
18241cb0ef41Sopenharmony_ci      FrameSummary::JavaScriptFrameSummary summary(
18251cb0ef41Sopenharmony_ci          isolate(), *receiver, *function, *abstract_code, code_offset,
18261cb0ef41Sopenharmony_ci          is_constructor, *params);
18271cb0ef41Sopenharmony_ci      frames->push_back(summary);
18281cb0ef41Sopenharmony_ci      is_constructor = false;
18291cb0ef41Sopenharmony_ci    } else if (it->kind() == TranslatedFrame::kConstructStub) {
18301cb0ef41Sopenharmony_ci      // The next encountered JS frame will be marked as a constructor call.
18311cb0ef41Sopenharmony_ci      DCHECK(!is_constructor);
18321cb0ef41Sopenharmony_ci      is_constructor = true;
18331cb0ef41Sopenharmony_ci    }
18341cb0ef41Sopenharmony_ci  }
18351cb0ef41Sopenharmony_ci}
18361cb0ef41Sopenharmony_ci
18371cb0ef41Sopenharmony_ciint OptimizedFrame::LookupExceptionHandlerInTable(
18381cb0ef41Sopenharmony_ci    int* data, HandlerTable::CatchPrediction* prediction) {
18391cb0ef41Sopenharmony_ci  // We cannot perform exception prediction on optimized code. Instead, we need
18401cb0ef41Sopenharmony_ci  // to use FrameSummary to find the corresponding code offset in unoptimized
18411cb0ef41Sopenharmony_ci  // code to perform prediction there.
18421cb0ef41Sopenharmony_ci  DCHECK_NULL(prediction);
18431cb0ef41Sopenharmony_ci  Code code = LookupCode();
18441cb0ef41Sopenharmony_ci  HandlerTable table(code);
18451cb0ef41Sopenharmony_ci  int pc_offset = code.GetOffsetFromInstructionStart(isolate(), pc());
18461cb0ef41Sopenharmony_ci  DCHECK_NULL(data);  // Data is not used and will not return a value.
18471cb0ef41Sopenharmony_ci
18481cb0ef41Sopenharmony_ci  // When the return pc has been replaced by a trampoline there won't be
18491cb0ef41Sopenharmony_ci  // a handler for this trampoline. Thus we need to use the return pc that
18501cb0ef41Sopenharmony_ci  // _used to be_ on the stack to get the right ExceptionHandler.
18511cb0ef41Sopenharmony_ci  if (CodeKindCanDeoptimize(code.kind()) && code.marked_for_deoptimization()) {
18521cb0ef41Sopenharmony_ci    SafepointTable safepoints(isolate(), pc(), code);
18531cb0ef41Sopenharmony_ci    pc_offset = safepoints.find_return_pc(pc_offset);
18541cb0ef41Sopenharmony_ci  }
18551cb0ef41Sopenharmony_ci  return table.LookupReturn(pc_offset);
18561cb0ef41Sopenharmony_ci}
18571cb0ef41Sopenharmony_ci
18581cb0ef41Sopenharmony_ciDeoptimizationData OptimizedFrame::GetDeoptimizationData(
18591cb0ef41Sopenharmony_ci    int* deopt_index) const {
18601cb0ef41Sopenharmony_ci  DCHECK(is_optimized());
18611cb0ef41Sopenharmony_ci
18621cb0ef41Sopenharmony_ci  JSFunction opt_function = function();
18631cb0ef41Sopenharmony_ci  Code code = FromCodeT(opt_function.code());
18641cb0ef41Sopenharmony_ci
18651cb0ef41Sopenharmony_ci  // The code object may have been replaced by lazy deoptimization. Fall
18661cb0ef41Sopenharmony_ci  // back to a slow search in this case to find the original optimized
18671cb0ef41Sopenharmony_ci  // code object.
18681cb0ef41Sopenharmony_ci  if (!code.contains(isolate(), pc())) {
18691cb0ef41Sopenharmony_ci    code = isolate()->heap()->GcSafeFindCodeForInnerPointer(pc());
18701cb0ef41Sopenharmony_ci  }
18711cb0ef41Sopenharmony_ci  DCHECK(!code.is_null());
18721cb0ef41Sopenharmony_ci  DCHECK(CodeKindCanDeoptimize(code.kind()));
18731cb0ef41Sopenharmony_ci
18741cb0ef41Sopenharmony_ci  SafepointEntry safepoint_entry = code.GetSafepointEntry(isolate(), pc());
18751cb0ef41Sopenharmony_ci  if (safepoint_entry.has_deoptimization_index()) {
18761cb0ef41Sopenharmony_ci    *deopt_index = safepoint_entry.deoptimization_index();
18771cb0ef41Sopenharmony_ci    return DeoptimizationData::cast(code.deoptimization_data());
18781cb0ef41Sopenharmony_ci  }
18791cb0ef41Sopenharmony_ci  *deopt_index = SafepointEntry::kNoDeoptIndex;
18801cb0ef41Sopenharmony_ci  return DeoptimizationData();
18811cb0ef41Sopenharmony_ci}
18821cb0ef41Sopenharmony_ci
18831cb0ef41Sopenharmony_civoid OptimizedFrame::GetFunctions(
18841cb0ef41Sopenharmony_ci    std::vector<SharedFunctionInfo>* functions) const {
18851cb0ef41Sopenharmony_ci  DCHECK(functions->empty());
18861cb0ef41Sopenharmony_ci  DCHECK(is_optimized());
18871cb0ef41Sopenharmony_ci
18881cb0ef41Sopenharmony_ci  // Delegate to JS frame in absence of turbofan deoptimization.
18891cb0ef41Sopenharmony_ci  // TODO(turbofan): Revisit once we support deoptimization across the board.
18901cb0ef41Sopenharmony_ci  Code code = LookupCode();
18911cb0ef41Sopenharmony_ci  if (code.kind() == CodeKind::BUILTIN) {
18921cb0ef41Sopenharmony_ci    return JavaScriptFrame::GetFunctions(functions);
18931cb0ef41Sopenharmony_ci  }
18941cb0ef41Sopenharmony_ci
18951cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
18961cb0ef41Sopenharmony_ci  int deopt_index = SafepointEntry::kNoDeoptIndex;
18971cb0ef41Sopenharmony_ci  DeoptimizationData const data = GetDeoptimizationData(&deopt_index);
18981cb0ef41Sopenharmony_ci  DCHECK(!data.is_null());
18991cb0ef41Sopenharmony_ci  DCHECK_NE(SafepointEntry::kNoDeoptIndex, deopt_index);
19001cb0ef41Sopenharmony_ci  DeoptimizationLiteralArray const literal_array = data.LiteralArray();
19011cb0ef41Sopenharmony_ci
19021cb0ef41Sopenharmony_ci  TranslationArrayIterator it(data.TranslationByteArray(),
19031cb0ef41Sopenharmony_ci                              data.TranslationIndex(deopt_index).value());
19041cb0ef41Sopenharmony_ci  TranslationOpcode opcode = TranslationOpcodeFromInt(it.Next());
19051cb0ef41Sopenharmony_ci  DCHECK_EQ(TranslationOpcode::BEGIN, opcode);
19061cb0ef41Sopenharmony_ci  it.Next();  // Skip frame count.
19071cb0ef41Sopenharmony_ci  int jsframe_count = it.Next();
19081cb0ef41Sopenharmony_ci  it.Next();  // Skip update feedback count.
19091cb0ef41Sopenharmony_ci
19101cb0ef41Sopenharmony_ci  // We insert the frames in reverse order because the frames
19111cb0ef41Sopenharmony_ci  // in the deoptimization translation are ordered bottom-to-top.
19121cb0ef41Sopenharmony_ci  while (jsframe_count != 0) {
19131cb0ef41Sopenharmony_ci    opcode = TranslationOpcodeFromInt(it.Next());
19141cb0ef41Sopenharmony_ci    if (opcode == TranslationOpcode::INTERPRETED_FRAME ||
19151cb0ef41Sopenharmony_ci        opcode == TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME ||
19161cb0ef41Sopenharmony_ci        opcode == TranslationOpcode::
19171cb0ef41Sopenharmony_ci                      JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) {
19181cb0ef41Sopenharmony_ci      it.Next();  // Skip bailout id.
19191cb0ef41Sopenharmony_ci      jsframe_count--;
19201cb0ef41Sopenharmony_ci
19211cb0ef41Sopenharmony_ci      // The second operand of the frame points to the function.
19221cb0ef41Sopenharmony_ci      Object shared = literal_array.get(it.Next());
19231cb0ef41Sopenharmony_ci      functions->push_back(SharedFunctionInfo::cast(shared));
19241cb0ef41Sopenharmony_ci
19251cb0ef41Sopenharmony_ci      // Skip over remaining operands to advance to the next opcode.
19261cb0ef41Sopenharmony_ci      it.Skip(TranslationOpcodeOperandCount(opcode) - 2);
19271cb0ef41Sopenharmony_ci    } else {
19281cb0ef41Sopenharmony_ci      // Skip over operands to advance to the next opcode.
19291cb0ef41Sopenharmony_ci      it.Skip(TranslationOpcodeOperandCount(opcode));
19301cb0ef41Sopenharmony_ci    }
19311cb0ef41Sopenharmony_ci  }
19321cb0ef41Sopenharmony_ci}
19331cb0ef41Sopenharmony_ci
19341cb0ef41Sopenharmony_ciint OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
19351cb0ef41Sopenharmony_ci  return StandardFrameConstants::kCallerSPOffset -
19361cb0ef41Sopenharmony_ci         ((slot_index + 1) * kSystemPointerSize);
19371cb0ef41Sopenharmony_ci}
19381cb0ef41Sopenharmony_ci
19391cb0ef41Sopenharmony_ciObject OptimizedFrame::StackSlotAt(int index) const {
19401cb0ef41Sopenharmony_ci  return Object(Memory<Address>(fp() + StackSlotOffsetRelativeToFp(index)));
19411cb0ef41Sopenharmony_ci}
19421cb0ef41Sopenharmony_ci
19431cb0ef41Sopenharmony_ciint UnoptimizedFrame::position() const {
19441cb0ef41Sopenharmony_ci  AbstractCode code = AbstractCode::cast(GetBytecodeArray());
19451cb0ef41Sopenharmony_ci  int code_offset = GetBytecodeOffset();
19461cb0ef41Sopenharmony_ci  return code.SourcePosition(code_offset);
19471cb0ef41Sopenharmony_ci}
19481cb0ef41Sopenharmony_ci
19491cb0ef41Sopenharmony_ciint UnoptimizedFrame::LookupExceptionHandlerInTable(
19501cb0ef41Sopenharmony_ci    int* context_register, HandlerTable::CatchPrediction* prediction) {
19511cb0ef41Sopenharmony_ci  HandlerTable table(GetBytecodeArray());
19521cb0ef41Sopenharmony_ci  return table.LookupRange(GetBytecodeOffset(), context_register, prediction);
19531cb0ef41Sopenharmony_ci}
19541cb0ef41Sopenharmony_ci
19551cb0ef41Sopenharmony_ciBytecodeArray UnoptimizedFrame::GetBytecodeArray() const {
19561cb0ef41Sopenharmony_ci  const int index = UnoptimizedFrameConstants::kBytecodeArrayExpressionIndex;
19571cb0ef41Sopenharmony_ci  DCHECK_EQ(UnoptimizedFrameConstants::kBytecodeArrayFromFp,
19581cb0ef41Sopenharmony_ci            UnoptimizedFrameConstants::kExpressionsOffset -
19591cb0ef41Sopenharmony_ci                index * kSystemPointerSize);
19601cb0ef41Sopenharmony_ci  return BytecodeArray::cast(GetExpression(index));
19611cb0ef41Sopenharmony_ci}
19621cb0ef41Sopenharmony_ci
19631cb0ef41Sopenharmony_ciObject UnoptimizedFrame::ReadInterpreterRegister(int register_index) const {
19641cb0ef41Sopenharmony_ci  const int index = UnoptimizedFrameConstants::kRegisterFileExpressionIndex;
19651cb0ef41Sopenharmony_ci  DCHECK_EQ(UnoptimizedFrameConstants::kRegisterFileFromFp,
19661cb0ef41Sopenharmony_ci            UnoptimizedFrameConstants::kExpressionsOffset -
19671cb0ef41Sopenharmony_ci                index * kSystemPointerSize);
19681cb0ef41Sopenharmony_ci  return GetExpression(index + register_index);
19691cb0ef41Sopenharmony_ci}
19701cb0ef41Sopenharmony_ci
19711cb0ef41Sopenharmony_civoid UnoptimizedFrame::Summarize(std::vector<FrameSummary>* functions) const {
19721cb0ef41Sopenharmony_ci  DCHECK(functions->empty());
19731cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code(AbstractCode::cast(GetBytecodeArray()),
19741cb0ef41Sopenharmony_ci                                     isolate());
19751cb0ef41Sopenharmony_ci  Handle<FixedArray> params = GetParameters();
19761cb0ef41Sopenharmony_ci  FrameSummary::JavaScriptFrameSummary summary(
19771cb0ef41Sopenharmony_ci      isolate(), receiver(), function(), *abstract_code, GetBytecodeOffset(),
19781cb0ef41Sopenharmony_ci      IsConstructor(), *params);
19791cb0ef41Sopenharmony_ci  functions->push_back(summary);
19801cb0ef41Sopenharmony_ci}
19811cb0ef41Sopenharmony_ci
19821cb0ef41Sopenharmony_ciint InterpretedFrame::GetBytecodeOffset() const {
19831cb0ef41Sopenharmony_ci  const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
19841cb0ef41Sopenharmony_ci  DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp,
19851cb0ef41Sopenharmony_ci            InterpreterFrameConstants::kExpressionsOffset -
19861cb0ef41Sopenharmony_ci                index * kSystemPointerSize);
19871cb0ef41Sopenharmony_ci  int raw_offset = Smi::ToInt(GetExpression(index));
19881cb0ef41Sopenharmony_ci  return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
19891cb0ef41Sopenharmony_ci}
19901cb0ef41Sopenharmony_ci
19911cb0ef41Sopenharmony_ci// static
19921cb0ef41Sopenharmony_ciint InterpretedFrame::GetBytecodeOffset(Address fp) {
19931cb0ef41Sopenharmony_ci  const int offset = InterpreterFrameConstants::kExpressionsOffset;
19941cb0ef41Sopenharmony_ci  const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
19951cb0ef41Sopenharmony_ci  DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp,
19961cb0ef41Sopenharmony_ci            InterpreterFrameConstants::kExpressionsOffset -
19971cb0ef41Sopenharmony_ci                index * kSystemPointerSize);
19981cb0ef41Sopenharmony_ci  Address expression_offset = fp + offset - index * kSystemPointerSize;
19991cb0ef41Sopenharmony_ci  int raw_offset = Smi::ToInt(Object(Memory<Address>(expression_offset)));
20001cb0ef41Sopenharmony_ci  return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
20011cb0ef41Sopenharmony_ci}
20021cb0ef41Sopenharmony_ci
20031cb0ef41Sopenharmony_civoid InterpretedFrame::PatchBytecodeOffset(int new_offset) {
20041cb0ef41Sopenharmony_ci  const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex;
20051cb0ef41Sopenharmony_ci  DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp,
20061cb0ef41Sopenharmony_ci            InterpreterFrameConstants::kExpressionsOffset -
20071cb0ef41Sopenharmony_ci                index * kSystemPointerSize);
20081cb0ef41Sopenharmony_ci  int raw_offset = BytecodeArray::kHeaderSize - kHeapObjectTag + new_offset;
20091cb0ef41Sopenharmony_ci  SetExpression(index, Smi::FromInt(raw_offset));
20101cb0ef41Sopenharmony_ci}
20111cb0ef41Sopenharmony_ci
20121cb0ef41Sopenharmony_civoid InterpretedFrame::PatchBytecodeArray(BytecodeArray bytecode_array) {
20131cb0ef41Sopenharmony_ci  const int index = InterpreterFrameConstants::kBytecodeArrayExpressionIndex;
20141cb0ef41Sopenharmony_ci  DCHECK_EQ(InterpreterFrameConstants::kBytecodeArrayFromFp,
20151cb0ef41Sopenharmony_ci            InterpreterFrameConstants::kExpressionsOffset -
20161cb0ef41Sopenharmony_ci                index * kSystemPointerSize);
20171cb0ef41Sopenharmony_ci  SetExpression(index, bytecode_array);
20181cb0ef41Sopenharmony_ci}
20191cb0ef41Sopenharmony_ci
20201cb0ef41Sopenharmony_ciint BaselineFrame::GetBytecodeOffset() const {
20211cb0ef41Sopenharmony_ci  return LookupCode().GetBytecodeOffsetForBaselinePC(this->pc(),
20221cb0ef41Sopenharmony_ci                                                     GetBytecodeArray());
20231cb0ef41Sopenharmony_ci}
20241cb0ef41Sopenharmony_ci
20251cb0ef41Sopenharmony_ciintptr_t BaselineFrame::GetPCForBytecodeOffset(int bytecode_offset) const {
20261cb0ef41Sopenharmony_ci  return LookupCode().GetBaselineStartPCForBytecodeOffset(bytecode_offset,
20271cb0ef41Sopenharmony_ci                                                          GetBytecodeArray());
20281cb0ef41Sopenharmony_ci}
20291cb0ef41Sopenharmony_ci
20301cb0ef41Sopenharmony_civoid BaselineFrame::PatchContext(Context value) {
20311cb0ef41Sopenharmony_ci  base::Memory<Address>(fp() + BaselineFrameConstants::kContextOffset) =
20321cb0ef41Sopenharmony_ci      value.ptr();
20331cb0ef41Sopenharmony_ci}
20341cb0ef41Sopenharmony_ci
20351cb0ef41Sopenharmony_ciJSFunction BuiltinFrame::function() const {
20361cb0ef41Sopenharmony_ci  const int offset = BuiltinFrameConstants::kFunctionOffset;
20371cb0ef41Sopenharmony_ci  return JSFunction::cast(Object(base::Memory<Address>(fp() + offset)));
20381cb0ef41Sopenharmony_ci}
20391cb0ef41Sopenharmony_ci
20401cb0ef41Sopenharmony_ciint BuiltinFrame::ComputeParametersCount() const {
20411cb0ef41Sopenharmony_ci  const int offset = BuiltinFrameConstants::kLengthOffset;
20421cb0ef41Sopenharmony_ci  return Smi::ToInt(Object(base::Memory<Address>(fp() + offset))) -
20431cb0ef41Sopenharmony_ci         kJSArgcReceiverSlots;
20441cb0ef41Sopenharmony_ci}
20451cb0ef41Sopenharmony_ci
20461cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
20471cb0ef41Sopenharmony_civoid WasmFrame::Print(StringStream* accumulator, PrintMode mode,
20481cb0ef41Sopenharmony_ci                      int index) const {
20491cb0ef41Sopenharmony_ci  PrintIndex(accumulator, mode, index);
20501cb0ef41Sopenharmony_ci  if (function_index() == wasm::kAnonymousFuncIndex) {
20511cb0ef41Sopenharmony_ci    accumulator->Add("Anonymous wasm wrapper [pc: %p]\n",
20521cb0ef41Sopenharmony_ci                     reinterpret_cast<void*>(pc()));
20531cb0ef41Sopenharmony_ci    return;
20541cb0ef41Sopenharmony_ci  }
20551cb0ef41Sopenharmony_ci  wasm::WasmCodeRefScope code_ref_scope;
20561cb0ef41Sopenharmony_ci  accumulator->Add("Wasm [");
20571cb0ef41Sopenharmony_ci  accumulator->PrintName(script().name());
20581cb0ef41Sopenharmony_ci  Address instruction_start = wasm_code()->instruction_start();
20591cb0ef41Sopenharmony_ci  base::Vector<const uint8_t> raw_func_name =
20601cb0ef41Sopenharmony_ci      module_object().GetRawFunctionName(function_index());
20611cb0ef41Sopenharmony_ci  const int kMaxPrintedFunctionName = 64;
20621cb0ef41Sopenharmony_ci  char func_name[kMaxPrintedFunctionName + 1];
20631cb0ef41Sopenharmony_ci  int func_name_len = std::min(kMaxPrintedFunctionName, raw_func_name.length());
20641cb0ef41Sopenharmony_ci  memcpy(func_name, raw_func_name.begin(), func_name_len);
20651cb0ef41Sopenharmony_ci  func_name[func_name_len] = '\0';
20661cb0ef41Sopenharmony_ci  int pos = position();
20671cb0ef41Sopenharmony_ci  const wasm::WasmModule* module = wasm_instance().module_object().module();
20681cb0ef41Sopenharmony_ci  int func_index = function_index();
20691cb0ef41Sopenharmony_ci  int func_code_offset = module->functions[func_index].code.offset();
20701cb0ef41Sopenharmony_ci  accumulator->Add("], function #%u ('%s'), pc=%p (+0x%x), pos=%d (+%d)\n",
20711cb0ef41Sopenharmony_ci                   func_index, func_name, reinterpret_cast<void*>(pc()),
20721cb0ef41Sopenharmony_ci                   static_cast<int>(pc() - instruction_start), pos,
20731cb0ef41Sopenharmony_ci                   pos - func_code_offset);
20741cb0ef41Sopenharmony_ci  if (mode != OVERVIEW) accumulator->Add("\n");
20751cb0ef41Sopenharmony_ci}
20761cb0ef41Sopenharmony_ci
20771cb0ef41Sopenharmony_ciwasm::WasmCode* WasmFrame::wasm_code() const {
20781cb0ef41Sopenharmony_ci  return wasm::GetWasmCodeManager()->LookupCode(pc());
20791cb0ef41Sopenharmony_ci}
20801cb0ef41Sopenharmony_ci
20811cb0ef41Sopenharmony_ciWasmInstanceObject WasmFrame::wasm_instance() const {
20821cb0ef41Sopenharmony_ci  const int offset = WasmFrameConstants::kWasmInstanceOffset;
20831cb0ef41Sopenharmony_ci  Object instance(Memory<Address>(fp() + offset));
20841cb0ef41Sopenharmony_ci  return WasmInstanceObject::cast(instance);
20851cb0ef41Sopenharmony_ci}
20861cb0ef41Sopenharmony_ci
20871cb0ef41Sopenharmony_ciwasm::NativeModule* WasmFrame::native_module() const {
20881cb0ef41Sopenharmony_ci  return module_object().native_module();
20891cb0ef41Sopenharmony_ci}
20901cb0ef41Sopenharmony_ci
20911cb0ef41Sopenharmony_ciWasmModuleObject WasmFrame::module_object() const {
20921cb0ef41Sopenharmony_ci  return wasm_instance().module_object();
20931cb0ef41Sopenharmony_ci}
20941cb0ef41Sopenharmony_ci
20951cb0ef41Sopenharmony_ciint WasmFrame::function_index() const {
20961cb0ef41Sopenharmony_ci  wasm::WasmCodeRefScope code_ref_scope;
20971cb0ef41Sopenharmony_ci  return wasm_code()->index();
20981cb0ef41Sopenharmony_ci}
20991cb0ef41Sopenharmony_ci
21001cb0ef41Sopenharmony_ciScript WasmFrame::script() const { return module_object().script(); }
21011cb0ef41Sopenharmony_ci
21021cb0ef41Sopenharmony_ciint WasmFrame::position() const {
21031cb0ef41Sopenharmony_ci  wasm::WasmCodeRefScope code_ref_scope;
21041cb0ef41Sopenharmony_ci  const wasm::WasmModule* module = wasm_instance().module_object().module();
21051cb0ef41Sopenharmony_ci  return GetSourcePosition(module, function_index(), byte_offset(),
21061cb0ef41Sopenharmony_ci                           at_to_number_conversion());
21071cb0ef41Sopenharmony_ci}
21081cb0ef41Sopenharmony_ci
21091cb0ef41Sopenharmony_ciint WasmFrame::byte_offset() const {
21101cb0ef41Sopenharmony_ci  wasm::WasmCode* code = wasm_code();
21111cb0ef41Sopenharmony_ci  int offset = static_cast<int>(pc() - code->instruction_start());
21121cb0ef41Sopenharmony_ci  return code->GetSourcePositionBefore(offset);
21131cb0ef41Sopenharmony_ci}
21141cb0ef41Sopenharmony_ci
21151cb0ef41Sopenharmony_cibool WasmFrame::is_inspectable() const {
21161cb0ef41Sopenharmony_ci  wasm::WasmCodeRefScope code_ref_scope;
21171cb0ef41Sopenharmony_ci  return wasm_code()->is_inspectable();
21181cb0ef41Sopenharmony_ci}
21191cb0ef41Sopenharmony_ci
21201cb0ef41Sopenharmony_ciObject WasmFrame::context() const { return wasm_instance().native_context(); }
21211cb0ef41Sopenharmony_ci
21221cb0ef41Sopenharmony_civoid WasmFrame::Summarize(std::vector<FrameSummary>* functions) const {
21231cb0ef41Sopenharmony_ci  DCHECK(functions->empty());
21241cb0ef41Sopenharmony_ci  // The {WasmCode*} escapes this scope via the {FrameSummary}, which is fine,
21251cb0ef41Sopenharmony_ci  // since this code object is part of our stack.
21261cb0ef41Sopenharmony_ci  wasm::WasmCodeRefScope code_ref_scope;
21271cb0ef41Sopenharmony_ci  wasm::WasmCode* code = wasm_code();
21281cb0ef41Sopenharmony_ci  int offset = static_cast<int>(pc() - code->instruction_start());
21291cb0ef41Sopenharmony_ci  Handle<WasmInstanceObject> instance(wasm_instance(), isolate());
21301cb0ef41Sopenharmony_ci  FrameSummary::WasmFrameSummary summary(isolate(), instance, code, offset,
21311cb0ef41Sopenharmony_ci                                         at_to_number_conversion());
21321cb0ef41Sopenharmony_ci  functions->push_back(summary);
21331cb0ef41Sopenharmony_ci}
21341cb0ef41Sopenharmony_ci
21351cb0ef41Sopenharmony_cibool WasmFrame::at_to_number_conversion() const {
21361cb0ef41Sopenharmony_ci  // Check whether our callee is a WASM_TO_JS frame, and this frame is at the
21371cb0ef41Sopenharmony_ci  // ToNumber conversion call.
21381cb0ef41Sopenharmony_ci  wasm::WasmCode* code =
21391cb0ef41Sopenharmony_ci      callee_pc() != kNullAddress
21401cb0ef41Sopenharmony_ci          ? wasm::GetWasmCodeManager()->LookupCode(callee_pc())
21411cb0ef41Sopenharmony_ci          : nullptr;
21421cb0ef41Sopenharmony_ci  if (!code || code->kind() != wasm::WasmCode::kWasmToJsWrapper) return false;
21431cb0ef41Sopenharmony_ci  int offset = static_cast<int>(callee_pc() - code->instruction_start());
21441cb0ef41Sopenharmony_ci  int pos = code->GetSourcePositionBefore(offset);
21451cb0ef41Sopenharmony_ci  // The imported call has position 0, ToNumber has position 1.
21461cb0ef41Sopenharmony_ci  // If there is no source position available, this is also not a ToNumber call.
21471cb0ef41Sopenharmony_ci  DCHECK(pos == wasm::kNoCodePosition || pos == 0 || pos == 1);
21481cb0ef41Sopenharmony_ci  return pos == 1;
21491cb0ef41Sopenharmony_ci}
21501cb0ef41Sopenharmony_ci
21511cb0ef41Sopenharmony_ciint WasmFrame::LookupExceptionHandlerInTable() {
21521cb0ef41Sopenharmony_ci  wasm::WasmCode* code = wasm::GetWasmCodeManager()->LookupCode(pc());
21531cb0ef41Sopenharmony_ci  if (!code->IsAnonymous() && code->handler_table_size() > 0) {
21541cb0ef41Sopenharmony_ci    HandlerTable table(code);
21551cb0ef41Sopenharmony_ci    int pc_offset = static_cast<int>(pc() - code->instruction_start());
21561cb0ef41Sopenharmony_ci    return table.LookupReturn(pc_offset);
21571cb0ef41Sopenharmony_ci  }
21581cb0ef41Sopenharmony_ci  return -1;
21591cb0ef41Sopenharmony_ci}
21601cb0ef41Sopenharmony_ci
21611cb0ef41Sopenharmony_civoid WasmDebugBreakFrame::Iterate(RootVisitor* v) const {
21621cb0ef41Sopenharmony_ci  DCHECK(caller_pc());
21631cb0ef41Sopenharmony_ci  wasm::WasmCode* code = wasm::GetWasmCodeManager()->LookupCode(caller_pc());
21641cb0ef41Sopenharmony_ci  DCHECK(code);
21651cb0ef41Sopenharmony_ci  SafepointTable table(code);
21661cb0ef41Sopenharmony_ci  SafepointEntry safepoint_entry = table.FindEntry(caller_pc());
21671cb0ef41Sopenharmony_ci  uint32_t tagged_register_indexes = safepoint_entry.tagged_register_indexes();
21681cb0ef41Sopenharmony_ci
21691cb0ef41Sopenharmony_ci  while (tagged_register_indexes != 0) {
21701cb0ef41Sopenharmony_ci    int reg_code = base::bits::CountTrailingZeros(tagged_register_indexes);
21711cb0ef41Sopenharmony_ci    tagged_register_indexes &= ~(1 << reg_code);
21721cb0ef41Sopenharmony_ci    FullObjectSlot spill_slot(&Memory<Address>(
21731cb0ef41Sopenharmony_ci        fp() +
21741cb0ef41Sopenharmony_ci        WasmDebugBreakFrameConstants::GetPushedGpRegisterOffset(reg_code)));
21751cb0ef41Sopenharmony_ci
21761cb0ef41Sopenharmony_ci    v->VisitRootPointer(Root::kStackRoots, nullptr, spill_slot);
21771cb0ef41Sopenharmony_ci  }
21781cb0ef41Sopenharmony_ci}
21791cb0ef41Sopenharmony_ci
21801cb0ef41Sopenharmony_civoid WasmDebugBreakFrame::Print(StringStream* accumulator, PrintMode mode,
21811cb0ef41Sopenharmony_ci                                int index) const {
21821cb0ef41Sopenharmony_ci  PrintIndex(accumulator, mode, index);
21831cb0ef41Sopenharmony_ci  accumulator->Add("WasmDebugBreak");
21841cb0ef41Sopenharmony_ci  if (mode != OVERVIEW) accumulator->Add("\n");
21851cb0ef41Sopenharmony_ci}
21861cb0ef41Sopenharmony_ci
21871cb0ef41Sopenharmony_civoid JsToWasmFrame::Iterate(RootVisitor* v) const {
21881cb0ef41Sopenharmony_ci  Code code = GetContainingCode(isolate(), pc());
21891cb0ef41Sopenharmony_ci  //  GenericJSToWasmWrapper stack layout
21901cb0ef41Sopenharmony_ci  //  ------+-----------------+----------------------
21911cb0ef41Sopenharmony_ci  //        |  return addr    |
21921cb0ef41Sopenharmony_ci  //    fp  |- - - - - - - - -|  -------------------|
21931cb0ef41Sopenharmony_ci  //        |       fp        |                     |
21941cb0ef41Sopenharmony_ci  //   fp-p |- - - - - - - - -|                     |
21951cb0ef41Sopenharmony_ci  //        |  frame marker   |                     | no GC scan
21961cb0ef41Sopenharmony_ci  //  fp-2p |- - - - - - - - -|                     |
21971cb0ef41Sopenharmony_ci  //        |   scan_count    |                     |
21981cb0ef41Sopenharmony_ci  //  fp-3p |- - - - - - - - -|  -------------------|
21991cb0ef41Sopenharmony_ci  //        |      ....       | <- spill_slot_limit |
22001cb0ef41Sopenharmony_ci  //        |   spill slots   |                     | GC scan scan_count slots
22011cb0ef41Sopenharmony_ci  //        |      ....       | <- spill_slot_base--|
22021cb0ef41Sopenharmony_ci  //        |- - - - - - - - -|                     |
22031cb0ef41Sopenharmony_ci  if (code.is_null() || !code.is_builtin() ||
22041cb0ef41Sopenharmony_ci      code.builtin_id() != Builtin::kGenericJSToWasmWrapper) {
22051cb0ef41Sopenharmony_ci    // If it's not the  GenericJSToWasmWrapper, then it's the TurboFan compiled
22061cb0ef41Sopenharmony_ci    // specific wrapper. So we have to call IterateCompiledFrame.
22071cb0ef41Sopenharmony_ci    IterateCompiledFrame(v);
22081cb0ef41Sopenharmony_ci    return;
22091cb0ef41Sopenharmony_ci  }
22101cb0ef41Sopenharmony_ci  // The [fp + BuiltinFrameConstants::kGCScanSlotCount] on the stack is a value
22111cb0ef41Sopenharmony_ci  // indicating how many values should be scanned from the top.
22121cb0ef41Sopenharmony_ci  intptr_t scan_count = *reinterpret_cast<intptr_t*>(
22131cb0ef41Sopenharmony_ci      fp() + BuiltinWasmWrapperConstants::kGCScanSlotCountOffset);
22141cb0ef41Sopenharmony_ci
22151cb0ef41Sopenharmony_ci  FullObjectSlot spill_slot_base(&Memory<Address>(sp()));
22161cb0ef41Sopenharmony_ci  FullObjectSlot spill_slot_limit(
22171cb0ef41Sopenharmony_ci      &Memory<Address>(sp() + scan_count * kSystemPointerSize));
22181cb0ef41Sopenharmony_ci  v->VisitRootPointers(Root::kStackRoots, nullptr, spill_slot_base,
22191cb0ef41Sopenharmony_ci                       spill_slot_limit);
22201cb0ef41Sopenharmony_ci}
22211cb0ef41Sopenharmony_ci
22221cb0ef41Sopenharmony_civoid StackSwitchFrame::Iterate(RootVisitor* v) const {
22231cb0ef41Sopenharmony_ci  //  See JsToWasmFrame layout.
22241cb0ef41Sopenharmony_ci  //  We cannot DCHECK that the pc matches the expected builtin code here,
22251cb0ef41Sopenharmony_ci  //  because the return address is on a different stack.
22261cb0ef41Sopenharmony_ci  // The [fp + BuiltinFrameConstants::kGCScanSlotCountOffset] on the stack is a
22271cb0ef41Sopenharmony_ci  // value indicating how many values should be scanned from the top.
22281cb0ef41Sopenharmony_ci  intptr_t scan_count = *reinterpret_cast<intptr_t*>(
22291cb0ef41Sopenharmony_ci      fp() + BuiltinWasmWrapperConstants::kGCScanSlotCountOffset);
22301cb0ef41Sopenharmony_ci
22311cb0ef41Sopenharmony_ci  FullObjectSlot spill_slot_base(&Memory<Address>(sp()));
22321cb0ef41Sopenharmony_ci  FullObjectSlot spill_slot_limit(
22331cb0ef41Sopenharmony_ci      &Memory<Address>(sp() + scan_count * kSystemPointerSize));
22341cb0ef41Sopenharmony_ci  v->VisitRootPointers(Root::kStackRoots, nullptr, spill_slot_base,
22351cb0ef41Sopenharmony_ci                       spill_slot_limit);
22361cb0ef41Sopenharmony_ci}
22371cb0ef41Sopenharmony_ci
22381cb0ef41Sopenharmony_ci// static
22391cb0ef41Sopenharmony_civoid StackSwitchFrame::GetStateForJumpBuffer(wasm::JumpBuffer* jmpbuf,
22401cb0ef41Sopenharmony_ci                                             State* state) {
22411cb0ef41Sopenharmony_ci  DCHECK_NE(jmpbuf->fp, kNullAddress);
22421cb0ef41Sopenharmony_ci  DCHECK_EQ(ComputeFrameType(jmpbuf->fp), STACK_SWITCH);
22431cb0ef41Sopenharmony_ci  FillState(jmpbuf->fp, jmpbuf->sp, state);
22441cb0ef41Sopenharmony_ci  DCHECK_NE(*state->pc_address, kNullAddress);
22451cb0ef41Sopenharmony_ci}
22461cb0ef41Sopenharmony_ci
22471cb0ef41Sopenharmony_ciWasmInstanceObject WasmCompileLazyFrame::wasm_instance() const {
22481cb0ef41Sopenharmony_ci  return WasmInstanceObject::cast(*wasm_instance_slot());
22491cb0ef41Sopenharmony_ci}
22501cb0ef41Sopenharmony_ci
22511cb0ef41Sopenharmony_ciFullObjectSlot WasmCompileLazyFrame::wasm_instance_slot() const {
22521cb0ef41Sopenharmony_ci  const int offset = WasmCompileLazyFrameConstants::kWasmInstanceOffset;
22531cb0ef41Sopenharmony_ci  return FullObjectSlot(&Memory<Address>(fp() + offset));
22541cb0ef41Sopenharmony_ci}
22551cb0ef41Sopenharmony_ci
22561cb0ef41Sopenharmony_civoid WasmCompileLazyFrame::Iterate(RootVisitor* v) const {
22571cb0ef41Sopenharmony_ci  const int header_size = WasmCompileLazyFrameConstants::kFixedFrameSizeFromFp;
22581cb0ef41Sopenharmony_ci  FullObjectSlot base(&Memory<Address>(sp()));
22591cb0ef41Sopenharmony_ci  FullObjectSlot limit(&Memory<Address>(fp() - header_size));
22601cb0ef41Sopenharmony_ci  v->VisitRootPointers(Root::kStackRoots, nullptr, base, limit);
22611cb0ef41Sopenharmony_ci  v->VisitRootPointer(Root::kStackRoots, nullptr, wasm_instance_slot());
22621cb0ef41Sopenharmony_ci}
22631cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
22641cb0ef41Sopenharmony_ci
22651cb0ef41Sopenharmony_cinamespace {
22661cb0ef41Sopenharmony_ci
22671cb0ef41Sopenharmony_civoid PrintFunctionSource(StringStream* accumulator, SharedFunctionInfo shared,
22681cb0ef41Sopenharmony_ci                         Code code) {
22691cb0ef41Sopenharmony_ci  if (FLAG_max_stack_trace_source_length != 0 && !code.is_null()) {
22701cb0ef41Sopenharmony_ci    std::ostringstream os;
22711cb0ef41Sopenharmony_ci    os << "--------- s o u r c e   c o d e ---------\n"
22721cb0ef41Sopenharmony_ci       << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
22731cb0ef41Sopenharmony_ci       << "\n-----------------------------------------\n";
22741cb0ef41Sopenharmony_ci    accumulator->Add(os.str().c_str());
22751cb0ef41Sopenharmony_ci  }
22761cb0ef41Sopenharmony_ci}
22771cb0ef41Sopenharmony_ci
22781cb0ef41Sopenharmony_ci}  // namespace
22791cb0ef41Sopenharmony_ci
22801cb0ef41Sopenharmony_civoid JavaScriptFrame::Print(StringStream* accumulator, PrintMode mode,
22811cb0ef41Sopenharmony_ci                            int index) const {
22821cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared = handle(function().shared(), isolate());
22831cb0ef41Sopenharmony_ci  SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate(), shared);
22841cb0ef41Sopenharmony_ci
22851cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
22861cb0ef41Sopenharmony_ci  Object receiver = this->receiver();
22871cb0ef41Sopenharmony_ci  JSFunction function = this->function();
22881cb0ef41Sopenharmony_ci
22891cb0ef41Sopenharmony_ci  accumulator->PrintSecurityTokenIfChanged(function);
22901cb0ef41Sopenharmony_ci  PrintIndex(accumulator, mode, index);
22911cb0ef41Sopenharmony_ci  PrintFrameKind(accumulator);
22921cb0ef41Sopenharmony_ci  Code code;
22931cb0ef41Sopenharmony_ci  if (IsConstructor()) accumulator->Add("new ");
22941cb0ef41Sopenharmony_ci  accumulator->PrintFunction(function, receiver, &code);
22951cb0ef41Sopenharmony_ci  accumulator->Add(" [%p]", function);
22961cb0ef41Sopenharmony_ci
22971cb0ef41Sopenharmony_ci  // Get scope information for nicer output, if possible. If code is nullptr, or
22981cb0ef41Sopenharmony_ci  // doesn't contain scope info, scope_info will return 0 for the number of
22991cb0ef41Sopenharmony_ci  // parameters, stack local variables, context local variables, stack slots,
23001cb0ef41Sopenharmony_ci  // or context slots.
23011cb0ef41Sopenharmony_ci  ScopeInfo scope_info = shared->scope_info();
23021cb0ef41Sopenharmony_ci  Object script_obj = shared->script();
23031cb0ef41Sopenharmony_ci  if (script_obj.IsScript()) {
23041cb0ef41Sopenharmony_ci    Script script = Script::cast(script_obj);
23051cb0ef41Sopenharmony_ci    accumulator->Add(" [");
23061cb0ef41Sopenharmony_ci    accumulator->PrintName(script.name());
23071cb0ef41Sopenharmony_ci
23081cb0ef41Sopenharmony_ci    if (is_interpreted()) {
23091cb0ef41Sopenharmony_ci      const InterpretedFrame* iframe = InterpretedFrame::cast(this);
23101cb0ef41Sopenharmony_ci      BytecodeArray bytecodes = iframe->GetBytecodeArray();
23111cb0ef41Sopenharmony_ci      int offset = iframe->GetBytecodeOffset();
23121cb0ef41Sopenharmony_ci      int source_pos = AbstractCode::cast(bytecodes).SourcePosition(offset);
23131cb0ef41Sopenharmony_ci      int line = script.GetLineNumber(source_pos) + 1;
23141cb0ef41Sopenharmony_ci      accumulator->Add(":%d] [bytecode=%p offset=%d]", line,
23151cb0ef41Sopenharmony_ci                       reinterpret_cast<void*>(bytecodes.ptr()), offset);
23161cb0ef41Sopenharmony_ci    } else {
23171cb0ef41Sopenharmony_ci      int function_start_pos = shared->StartPosition();
23181cb0ef41Sopenharmony_ci      int line = script.GetLineNumber(function_start_pos) + 1;
23191cb0ef41Sopenharmony_ci      accumulator->Add(":~%d] [pc=%p]", line, reinterpret_cast<void*>(pc()));
23201cb0ef41Sopenharmony_ci    }
23211cb0ef41Sopenharmony_ci  }
23221cb0ef41Sopenharmony_ci
23231cb0ef41Sopenharmony_ci  accumulator->Add("(this=%o", receiver);
23241cb0ef41Sopenharmony_ci
23251cb0ef41Sopenharmony_ci  // Print the parameters.
23261cb0ef41Sopenharmony_ci  int parameters_count = ComputeParametersCount();
23271cb0ef41Sopenharmony_ci  for (int i = 0; i < parameters_count; i++) {
23281cb0ef41Sopenharmony_ci    accumulator->Add(",");
23291cb0ef41Sopenharmony_ci    accumulator->Add("%o", GetParameter(i));
23301cb0ef41Sopenharmony_ci  }
23311cb0ef41Sopenharmony_ci
23321cb0ef41Sopenharmony_ci  accumulator->Add(")");
23331cb0ef41Sopenharmony_ci  if (mode == OVERVIEW) {
23341cb0ef41Sopenharmony_ci    accumulator->Add("\n");
23351cb0ef41Sopenharmony_ci    return;
23361cb0ef41Sopenharmony_ci  }
23371cb0ef41Sopenharmony_ci  if (is_optimized()) {
23381cb0ef41Sopenharmony_ci    accumulator->Add(" {\n// optimized frame\n");
23391cb0ef41Sopenharmony_ci    PrintFunctionSource(accumulator, *shared, code);
23401cb0ef41Sopenharmony_ci    accumulator->Add("}\n");
23411cb0ef41Sopenharmony_ci    return;
23421cb0ef41Sopenharmony_ci  }
23431cb0ef41Sopenharmony_ci  accumulator->Add(" {\n");
23441cb0ef41Sopenharmony_ci
23451cb0ef41Sopenharmony_ci  // Compute the number of locals and expression stack elements.
23461cb0ef41Sopenharmony_ci  int heap_locals_count = scope_info.ContextLocalCount();
23471cb0ef41Sopenharmony_ci  int expressions_count = ComputeExpressionsCount();
23481cb0ef41Sopenharmony_ci
23491cb0ef41Sopenharmony_ci  // Try to get hold of the context of this frame.
23501cb0ef41Sopenharmony_ci  Context context;
23511cb0ef41Sopenharmony_ci  if (this->context().IsContext()) {
23521cb0ef41Sopenharmony_ci    context = Context::cast(this->context());
23531cb0ef41Sopenharmony_ci    while (context.IsWithContext()) {
23541cb0ef41Sopenharmony_ci      context = context.previous();
23551cb0ef41Sopenharmony_ci      DCHECK(!context.is_null());
23561cb0ef41Sopenharmony_ci    }
23571cb0ef41Sopenharmony_ci  }
23581cb0ef41Sopenharmony_ci
23591cb0ef41Sopenharmony_ci  // Print heap-allocated local variables.
23601cb0ef41Sopenharmony_ci  if (heap_locals_count > 0) {
23611cb0ef41Sopenharmony_ci    accumulator->Add("  // heap-allocated locals\n");
23621cb0ef41Sopenharmony_ci  }
23631cb0ef41Sopenharmony_ci  for (auto it : ScopeInfo::IterateLocalNames(&scope_info, no_gc)) {
23641cb0ef41Sopenharmony_ci    accumulator->Add("  var ");
23651cb0ef41Sopenharmony_ci    accumulator->PrintName(it->name());
23661cb0ef41Sopenharmony_ci    accumulator->Add(" = ");
23671cb0ef41Sopenharmony_ci    if (!context.is_null()) {
23681cb0ef41Sopenharmony_ci      int slot_index = Context::MIN_CONTEXT_SLOTS + it->index();
23691cb0ef41Sopenharmony_ci      if (slot_index < context.length()) {
23701cb0ef41Sopenharmony_ci        accumulator->Add("%o", context.get(slot_index));
23711cb0ef41Sopenharmony_ci      } else {
23721cb0ef41Sopenharmony_ci        accumulator->Add(
23731cb0ef41Sopenharmony_ci            "// warning: missing context slot - inconsistent frame?");
23741cb0ef41Sopenharmony_ci      }
23751cb0ef41Sopenharmony_ci    } else {
23761cb0ef41Sopenharmony_ci      accumulator->Add("// warning: no context found - inconsistent frame?");
23771cb0ef41Sopenharmony_ci    }
23781cb0ef41Sopenharmony_ci    accumulator->Add("\n");
23791cb0ef41Sopenharmony_ci  }
23801cb0ef41Sopenharmony_ci
23811cb0ef41Sopenharmony_ci  // Print the expression stack.
23821cb0ef41Sopenharmony_ci  if (0 < expressions_count) {
23831cb0ef41Sopenharmony_ci    accumulator->Add("  // expression stack (top to bottom)\n");
23841cb0ef41Sopenharmony_ci  }
23851cb0ef41Sopenharmony_ci  for (int i = expressions_count - 1; i >= 0; i--) {
23861cb0ef41Sopenharmony_ci    accumulator->Add("  [%02d] : %o\n", i, GetExpression(i));
23871cb0ef41Sopenharmony_ci  }
23881cb0ef41Sopenharmony_ci
23891cb0ef41Sopenharmony_ci  PrintFunctionSource(accumulator, *shared, code);
23901cb0ef41Sopenharmony_ci
23911cb0ef41Sopenharmony_ci  accumulator->Add("}\n\n");
23921cb0ef41Sopenharmony_ci}
23931cb0ef41Sopenharmony_ci
23941cb0ef41Sopenharmony_civoid EntryFrame::Iterate(RootVisitor* v) const {
23951cb0ef41Sopenharmony_ci  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
23961cb0ef41Sopenharmony_ci}
23971cb0ef41Sopenharmony_ci
23981cb0ef41Sopenharmony_civoid CommonFrame::IterateExpressions(RootVisitor* v) const {
23991cb0ef41Sopenharmony_ci  const int last_object_offset = StandardFrameConstants::kLastObjectOffset;
24001cb0ef41Sopenharmony_ci  intptr_t marker =
24011cb0ef41Sopenharmony_ci      Memory<intptr_t>(fp() + CommonFrameConstants::kContextOrFrameTypeOffset);
24021cb0ef41Sopenharmony_ci  FullObjectSlot base(&Memory<Address>(sp()));
24031cb0ef41Sopenharmony_ci  FullObjectSlot limit(&Memory<Address>(fp() + last_object_offset) + 1);
24041cb0ef41Sopenharmony_ci  if (StackFrame::IsTypeMarker(marker)) {
24051cb0ef41Sopenharmony_ci    v->VisitRootPointers(Root::kStackRoots, nullptr, base, limit);
24061cb0ef41Sopenharmony_ci  } else {
24071cb0ef41Sopenharmony_ci    // The frame contains the actual argument count (intptr) that should not be
24081cb0ef41Sopenharmony_ci    // visited.
24091cb0ef41Sopenharmony_ci    FullObjectSlot argc(
24101cb0ef41Sopenharmony_ci        &Memory<Address>(fp() + StandardFrameConstants::kArgCOffset));
24111cb0ef41Sopenharmony_ci    v->VisitRootPointers(Root::kStackRoots, nullptr, base, argc);
24121cb0ef41Sopenharmony_ci    v->VisitRootPointers(Root::kStackRoots, nullptr, argc + 1, limit);
24131cb0ef41Sopenharmony_ci  }
24141cb0ef41Sopenharmony_ci}
24151cb0ef41Sopenharmony_ci
24161cb0ef41Sopenharmony_civoid JavaScriptFrame::Iterate(RootVisitor* v) const {
24171cb0ef41Sopenharmony_ci  IterateExpressions(v);
24181cb0ef41Sopenharmony_ci  IteratePc(v, pc_address(), constant_pool_address(), LookupCode());
24191cb0ef41Sopenharmony_ci}
24201cb0ef41Sopenharmony_ci
24211cb0ef41Sopenharmony_civoid InternalFrame::Iterate(RootVisitor* v) const {
24221cb0ef41Sopenharmony_ci  Code code = LookupCode();
24231cb0ef41Sopenharmony_ci  IteratePc(v, pc_address(), constant_pool_address(), code);
24241cb0ef41Sopenharmony_ci  // Internal frames typically do not receive any arguments, hence their stack
24251cb0ef41Sopenharmony_ci  // only contains tagged pointers.
24261cb0ef41Sopenharmony_ci  // We are misusing the has_tagged_outgoing_params flag here to tell us whether
24271cb0ef41Sopenharmony_ci  // the full stack frame contains only tagged pointers or only raw values.
24281cb0ef41Sopenharmony_ci  // This is used for the WasmCompileLazy builtin, where we actually pass
24291cb0ef41Sopenharmony_ci  // untagged arguments and also store untagged values on the stack.
24301cb0ef41Sopenharmony_ci  if (code.has_tagged_outgoing_params()) IterateExpressions(v);
24311cb0ef41Sopenharmony_ci}
24321cb0ef41Sopenharmony_ci
24331cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
24341cb0ef41Sopenharmony_ci
24351cb0ef41Sopenharmony_cinamespace {
24361cb0ef41Sopenharmony_ci
24371cb0ef41Sopenharmony_ci// Predictably converts PC to uint32 by calculating offset of the PC in
24381cb0ef41Sopenharmony_ci// from the embedded builtins start or from respective MemoryChunk.
24391cb0ef41Sopenharmony_ciuint32_t PcAddressForHashing(Isolate* isolate, Address address) {
24401cb0ef41Sopenharmony_ci  uint32_t hashable_address;
24411cb0ef41Sopenharmony_ci  if (OffHeapInstructionStream::TryGetAddressForHashing(isolate, address,
24421cb0ef41Sopenharmony_ci                                                        &hashable_address)) {
24431cb0ef41Sopenharmony_ci    return hashable_address;
24441cb0ef41Sopenharmony_ci  }
24451cb0ef41Sopenharmony_ci  return ObjectAddressForHashing(address);
24461cb0ef41Sopenharmony_ci}
24471cb0ef41Sopenharmony_ci
24481cb0ef41Sopenharmony_ci}  // namespace
24491cb0ef41Sopenharmony_ci
24501cb0ef41Sopenharmony_ciInnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
24511cb0ef41Sopenharmony_ciInnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
24521cb0ef41Sopenharmony_ci  isolate_->counters()->pc_to_code()->Increment();
24531cb0ef41Sopenharmony_ci  DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
24541cb0ef41Sopenharmony_ci  uint32_t hash =
24551cb0ef41Sopenharmony_ci      ComputeUnseededHash(PcAddressForHashing(isolate_, inner_pointer));
24561cb0ef41Sopenharmony_ci  uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
24571cb0ef41Sopenharmony_ci  InnerPointerToCodeCacheEntry* entry = cache(index);
24581cb0ef41Sopenharmony_ci  if (entry->inner_pointer == inner_pointer) {
24591cb0ef41Sopenharmony_ci    isolate_->counters()->pc_to_code_cached()->Increment();
24601cb0ef41Sopenharmony_ci    DCHECK(entry->code ==
24611cb0ef41Sopenharmony_ci           isolate_->heap()->GcSafeFindCodeForInnerPointer(inner_pointer));
24621cb0ef41Sopenharmony_ci  } else {
24631cb0ef41Sopenharmony_ci    // Because this code may be interrupted by a profiling signal that
24641cb0ef41Sopenharmony_ci    // also queries the cache, we cannot update inner_pointer before the code
24651cb0ef41Sopenharmony_ci    // has been set. Otherwise, we risk trying to use a cache entry before
24661cb0ef41Sopenharmony_ci    // the code has been computed.
24671cb0ef41Sopenharmony_ci    entry->code =
24681cb0ef41Sopenharmony_ci        isolate_->heap()->GcSafeFindCodeForInnerPointer(inner_pointer);
24691cb0ef41Sopenharmony_ci    entry->safepoint_entry.Reset();
24701cb0ef41Sopenharmony_ci    entry->inner_pointer = inner_pointer;
24711cb0ef41Sopenharmony_ci  }
24721cb0ef41Sopenharmony_ci  return entry;
24731cb0ef41Sopenharmony_ci}
24741cb0ef41Sopenharmony_ci
24751cb0ef41Sopenharmony_ci// Frame layout helper class implementation.
24761cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
24771cb0ef41Sopenharmony_ci
24781cb0ef41Sopenharmony_cinamespace {
24791cb0ef41Sopenharmony_ci
24801cb0ef41Sopenharmony_ci// Some architectures need to push padding together with the TOS register
24811cb0ef41Sopenharmony_ci// in order to maintain stack alignment.
24821cb0ef41Sopenharmony_ciconstexpr int TopOfStackRegisterPaddingSlots() {
24831cb0ef41Sopenharmony_ci  return ArgumentPaddingSlots(1);
24841cb0ef41Sopenharmony_ci}
24851cb0ef41Sopenharmony_ci
24861cb0ef41Sopenharmony_cibool BuiltinContinuationModeIsWithCatch(BuiltinContinuationMode mode) {
24871cb0ef41Sopenharmony_ci  switch (mode) {
24881cb0ef41Sopenharmony_ci    case BuiltinContinuationMode::STUB:
24891cb0ef41Sopenharmony_ci    case BuiltinContinuationMode::JAVASCRIPT:
24901cb0ef41Sopenharmony_ci      return false;
24911cb0ef41Sopenharmony_ci    case BuiltinContinuationMode::JAVASCRIPT_WITH_CATCH:
24921cb0ef41Sopenharmony_ci    case BuiltinContinuationMode::JAVASCRIPT_HANDLE_EXCEPTION:
24931cb0ef41Sopenharmony_ci      return true;
24941cb0ef41Sopenharmony_ci  }
24951cb0ef41Sopenharmony_ci  UNREACHABLE();
24961cb0ef41Sopenharmony_ci}
24971cb0ef41Sopenharmony_ci
24981cb0ef41Sopenharmony_ci}  // namespace
24991cb0ef41Sopenharmony_ci
25001cb0ef41Sopenharmony_ciUnoptimizedFrameInfo::UnoptimizedFrameInfo(int parameters_count_with_receiver,
25011cb0ef41Sopenharmony_ci                                           int translation_height,
25021cb0ef41Sopenharmony_ci                                           bool is_topmost, bool pad_arguments,
25031cb0ef41Sopenharmony_ci                                           FrameInfoKind frame_info_kind) {
25041cb0ef41Sopenharmony_ci  const int locals_count = translation_height;
25051cb0ef41Sopenharmony_ci
25061cb0ef41Sopenharmony_ci  register_stack_slot_count_ =
25071cb0ef41Sopenharmony_ci      UnoptimizedFrameConstants::RegisterStackSlotCount(locals_count);
25081cb0ef41Sopenharmony_ci
25091cb0ef41Sopenharmony_ci  static constexpr int kTheAccumulator = 1;
25101cb0ef41Sopenharmony_ci  static constexpr int kTopOfStackPadding = TopOfStackRegisterPaddingSlots();
25111cb0ef41Sopenharmony_ci  int maybe_additional_slots =
25121cb0ef41Sopenharmony_ci      (is_topmost || frame_info_kind == FrameInfoKind::kConservative)
25131cb0ef41Sopenharmony_ci          ? (kTheAccumulator + kTopOfStackPadding)
25141cb0ef41Sopenharmony_ci          : 0;
25151cb0ef41Sopenharmony_ci  frame_size_in_bytes_without_fixed_ =
25161cb0ef41Sopenharmony_ci      (register_stack_slot_count_ + maybe_additional_slots) *
25171cb0ef41Sopenharmony_ci      kSystemPointerSize;
25181cb0ef41Sopenharmony_ci
25191cb0ef41Sopenharmony_ci  // The 'fixed' part of the frame consists of the incoming parameters and
25201cb0ef41Sopenharmony_ci  // the part described by InterpreterFrameConstants. This will include
25211cb0ef41Sopenharmony_ci  // argument padding, when needed.
25221cb0ef41Sopenharmony_ci  const int parameter_padding_slots =
25231cb0ef41Sopenharmony_ci      pad_arguments ? ArgumentPaddingSlots(parameters_count_with_receiver) : 0;
25241cb0ef41Sopenharmony_ci  const int fixed_frame_size =
25251cb0ef41Sopenharmony_ci      InterpreterFrameConstants::kFixedFrameSize +
25261cb0ef41Sopenharmony_ci      (parameters_count_with_receiver + parameter_padding_slots) *
25271cb0ef41Sopenharmony_ci          kSystemPointerSize;
25281cb0ef41Sopenharmony_ci  frame_size_in_bytes_ = frame_size_in_bytes_without_fixed_ + fixed_frame_size;
25291cb0ef41Sopenharmony_ci}
25301cb0ef41Sopenharmony_ci
25311cb0ef41Sopenharmony_ci// static
25321cb0ef41Sopenharmony_ciuint32_t UnoptimizedFrameInfo::GetStackSizeForAdditionalArguments(
25331cb0ef41Sopenharmony_ci    int parameters_count) {
25341cb0ef41Sopenharmony_ci  return (parameters_count + ArgumentPaddingSlots(parameters_count)) *
25351cb0ef41Sopenharmony_ci         kSystemPointerSize;
25361cb0ef41Sopenharmony_ci}
25371cb0ef41Sopenharmony_ci
25381cb0ef41Sopenharmony_ciConstructStubFrameInfo::ConstructStubFrameInfo(int translation_height,
25391cb0ef41Sopenharmony_ci                                               bool is_topmost,
25401cb0ef41Sopenharmony_ci                                               FrameInfoKind frame_info_kind) {
25411cb0ef41Sopenharmony_ci  // Note: This is according to the Translation's notion of 'parameters' which
25421cb0ef41Sopenharmony_ci  // differs to that of the SharedFunctionInfo, e.g. by including the receiver.
25431cb0ef41Sopenharmony_ci  const int parameters_count = translation_height;
25441cb0ef41Sopenharmony_ci
25451cb0ef41Sopenharmony_ci  // If the construct frame appears to be topmost we should ensure that the
25461cb0ef41Sopenharmony_ci  // value of result register is preserved during continuation execution.
25471cb0ef41Sopenharmony_ci  // We do this here by "pushing" the result of the constructor function to
25481cb0ef41Sopenharmony_ci  // the top of the reconstructed stack and popping it in
25491cb0ef41Sopenharmony_ci  // {Builtin::kNotifyDeoptimized}.
25501cb0ef41Sopenharmony_ci
25511cb0ef41Sopenharmony_ci  static constexpr int kTopOfStackPadding = TopOfStackRegisterPaddingSlots();
25521cb0ef41Sopenharmony_ci  static constexpr int kTheResult = 1;
25531cb0ef41Sopenharmony_ci  const int argument_padding = ArgumentPaddingSlots(parameters_count);
25541cb0ef41Sopenharmony_ci
25551cb0ef41Sopenharmony_ci  const int adjusted_height =
25561cb0ef41Sopenharmony_ci      (is_topmost || frame_info_kind == FrameInfoKind::kConservative)
25571cb0ef41Sopenharmony_ci          ? parameters_count + argument_padding + kTheResult +
25581cb0ef41Sopenharmony_ci                kTopOfStackPadding
25591cb0ef41Sopenharmony_ci          : parameters_count + argument_padding;
25601cb0ef41Sopenharmony_ci  frame_size_in_bytes_without_fixed_ = adjusted_height * kSystemPointerSize;
25611cb0ef41Sopenharmony_ci  frame_size_in_bytes_ = frame_size_in_bytes_without_fixed_ +
25621cb0ef41Sopenharmony_ci                         ConstructFrameConstants::kFixedFrameSize;
25631cb0ef41Sopenharmony_ci}
25641cb0ef41Sopenharmony_ci
25651cb0ef41Sopenharmony_ciBuiltinContinuationFrameInfo::BuiltinContinuationFrameInfo(
25661cb0ef41Sopenharmony_ci    int translation_height,
25671cb0ef41Sopenharmony_ci    const CallInterfaceDescriptor& continuation_descriptor,
25681cb0ef41Sopenharmony_ci    const RegisterConfiguration* register_config, bool is_topmost,
25691cb0ef41Sopenharmony_ci    DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode,
25701cb0ef41Sopenharmony_ci    FrameInfoKind frame_info_kind) {
25711cb0ef41Sopenharmony_ci  const bool is_conservative = frame_info_kind == FrameInfoKind::kConservative;
25721cb0ef41Sopenharmony_ci
25731cb0ef41Sopenharmony_ci  // Note: This is according to the Translation's notion of 'parameters' which
25741cb0ef41Sopenharmony_ci  // differs to that of the SharedFunctionInfo, e.g. by including the receiver.
25751cb0ef41Sopenharmony_ci  const int parameters_count = translation_height;
25761cb0ef41Sopenharmony_ci  frame_has_result_stack_slot_ =
25771cb0ef41Sopenharmony_ci      !is_topmost || deopt_kind == DeoptimizeKind::kLazy;
25781cb0ef41Sopenharmony_ci  const int result_slot_count =
25791cb0ef41Sopenharmony_ci      (frame_has_result_stack_slot_ || is_conservative) ? 1 : 0;
25801cb0ef41Sopenharmony_ci
25811cb0ef41Sopenharmony_ci  const int exception_slot_count =
25821cb0ef41Sopenharmony_ci      (BuiltinContinuationModeIsWithCatch(continuation_mode) || is_conservative)
25831cb0ef41Sopenharmony_ci          ? 1
25841cb0ef41Sopenharmony_ci          : 0;
25851cb0ef41Sopenharmony_ci
25861cb0ef41Sopenharmony_ci  const int allocatable_register_count =
25871cb0ef41Sopenharmony_ci      register_config->num_allocatable_general_registers();
25881cb0ef41Sopenharmony_ci  const int padding_slot_count =
25891cb0ef41Sopenharmony_ci      BuiltinContinuationFrameConstants::PaddingSlotCount(
25901cb0ef41Sopenharmony_ci          allocatable_register_count);
25911cb0ef41Sopenharmony_ci
25921cb0ef41Sopenharmony_ci  const int register_parameter_count =
25931cb0ef41Sopenharmony_ci      continuation_descriptor.GetRegisterParameterCount();
25941cb0ef41Sopenharmony_ci  translated_stack_parameter_count_ =
25951cb0ef41Sopenharmony_ci      parameters_count - register_parameter_count;
25961cb0ef41Sopenharmony_ci  stack_parameter_count_ = translated_stack_parameter_count_ +
25971cb0ef41Sopenharmony_ci                           result_slot_count + exception_slot_count;
25981cb0ef41Sopenharmony_ci  const int stack_param_pad_count =
25991cb0ef41Sopenharmony_ci      ArgumentPaddingSlots(stack_parameter_count_);
26001cb0ef41Sopenharmony_ci
26011cb0ef41Sopenharmony_ci  // If the builtins frame appears to be topmost we should ensure that the
26021cb0ef41Sopenharmony_ci  // value of result register is preserved during continuation execution.
26031cb0ef41Sopenharmony_ci  // We do this here by "pushing" the result of callback function to the
26041cb0ef41Sopenharmony_ci  // top of the reconstructed stack and popping it in
26051cb0ef41Sopenharmony_ci  // {Builtin::kNotifyDeoptimized}.
26061cb0ef41Sopenharmony_ci  static constexpr int kTopOfStackPadding = TopOfStackRegisterPaddingSlots();
26071cb0ef41Sopenharmony_ci  static constexpr int kTheResult = 1;
26081cb0ef41Sopenharmony_ci  const int push_result_count =
26091cb0ef41Sopenharmony_ci      (is_topmost || is_conservative) ? kTheResult + kTopOfStackPadding : 0;
26101cb0ef41Sopenharmony_ci
26111cb0ef41Sopenharmony_ci  frame_size_in_bytes_ =
26121cb0ef41Sopenharmony_ci      kSystemPointerSize * (stack_parameter_count_ + stack_param_pad_count +
26131cb0ef41Sopenharmony_ci                            allocatable_register_count + padding_slot_count +
26141cb0ef41Sopenharmony_ci                            push_result_count) +
26151cb0ef41Sopenharmony_ci      BuiltinContinuationFrameConstants::kFixedFrameSize;
26161cb0ef41Sopenharmony_ci
26171cb0ef41Sopenharmony_ci  frame_size_in_bytes_above_fp_ =
26181cb0ef41Sopenharmony_ci      kSystemPointerSize * (allocatable_register_count + padding_slot_count +
26191cb0ef41Sopenharmony_ci                            push_result_count) +
26201cb0ef41Sopenharmony_ci      (BuiltinContinuationFrameConstants::kFixedFrameSize -
26211cb0ef41Sopenharmony_ci       BuiltinContinuationFrameConstants::kFixedFrameSizeAboveFp);
26221cb0ef41Sopenharmony_ci}
26231cb0ef41Sopenharmony_ci
26241cb0ef41Sopenharmony_ci}  // namespace internal
26251cb0ef41Sopenharmony_ci}  // namespace v8
2626