11cb0ef41Sopenharmony_ci// Copyright 2019 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/objects/code.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <iomanip>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "src/codegen/assembler-inl.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/cpu-features.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/reloc-info.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/safepoint-table.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/source-position.h"
141cb0ef41Sopenharmony_ci#include "src/deoptimizer/deoptimizer.h"
151cb0ef41Sopenharmony_ci#include "src/execution/isolate-utils-inl.h"
161cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-array-iterator.h"
171cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-decoder.h"
181cb0ef41Sopenharmony_ci#include "src/interpreter/interpreter.h"
191cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h"
201cb0ef41Sopenharmony_ci#include "src/objects/code-kind.h"
211cb0ef41Sopenharmony_ci#include "src/objects/fixed-array.h"
221cb0ef41Sopenharmony_ci#include "src/roots/roots-inl.h"
231cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/embedded-data-inl.h"
241cb0ef41Sopenharmony_ci#include "src/utils/ostreams.h"
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
271cb0ef41Sopenharmony_ci#include "src/codegen/code-comments.h"
281cb0ef41Sopenharmony_ci#include "src/diagnostics/disasm.h"
291cb0ef41Sopenharmony_ci#include "src/diagnostics/disassembler.h"
301cb0ef41Sopenharmony_ci#include "src/diagnostics/eh-frame.h"
311cb0ef41Sopenharmony_ci#endif
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cinamespace v8 {
341cb0ef41Sopenharmony_cinamespace internal {
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cinamespace {
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// Helper function for getting an EmbeddedData that can handle un-embedded
391cb0ef41Sopenharmony_ci// builtins when short builtin calls are enabled.
401cb0ef41Sopenharmony_ciinline EmbeddedData EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(
411cb0ef41Sopenharmony_ci    HeapObject code) {
421cb0ef41Sopenharmony_ci#if defined(V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE)
431cb0ef41Sopenharmony_ci  // GetIsolateFromWritableObject(*this) works for both read-only and writable
441cb0ef41Sopenharmony_ci  // objects when pointer compression is enabled with a per-Isolate cage.
451cb0ef41Sopenharmony_ci  return EmbeddedData::FromBlob(GetIsolateFromWritableObject(code));
461cb0ef41Sopenharmony_ci#elif defined(V8_COMPRESS_POINTERS_IN_SHARED_CAGE)
471cb0ef41Sopenharmony_ci  // When pointer compression is enabled with a shared cage, there is also a
481cb0ef41Sopenharmony_ci  // shared CodeRange. When short builtin calls are enabled, there is a single
491cb0ef41Sopenharmony_ci  // copy of the re-embedded builtins in the shared CodeRange, so use that if
501cb0ef41Sopenharmony_ci  // it's present.
511cb0ef41Sopenharmony_ci  if (FLAG_jitless) return EmbeddedData::FromBlob();
521cb0ef41Sopenharmony_ci  CodeRange* code_range = CodeRange::GetProcessWideCodeRange().get();
531cb0ef41Sopenharmony_ci  return (code_range && code_range->embedded_blob_code_copy() != nullptr)
541cb0ef41Sopenharmony_ci             ? EmbeddedData::FromBlob(code_range)
551cb0ef41Sopenharmony_ci             : EmbeddedData::FromBlob();
561cb0ef41Sopenharmony_ci#else
571cb0ef41Sopenharmony_ci  // Otherwise there is a single copy of the blob across all Isolates, use the
581cb0ef41Sopenharmony_ci  // global atomic variables.
591cb0ef41Sopenharmony_ci  return EmbeddedData::FromBlob();
601cb0ef41Sopenharmony_ci#endif
611cb0ef41Sopenharmony_ci}
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci}  // namespace
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ciAddress OffHeapInstructionStart(HeapObject code, Builtin builtin) {
661cb0ef41Sopenharmony_ci  // TODO(11527): Here and below: pass Isolate as an argument for getting
671cb0ef41Sopenharmony_ci  // the EmbeddedData.
681cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
691cb0ef41Sopenharmony_ci  return d.InstructionStartOfBuiltin(builtin);
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciAddress OffHeapInstructionEnd(HeapObject code, Builtin builtin) {
731cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
741cb0ef41Sopenharmony_ci  return d.InstructionStartOfBuiltin(builtin) +
751cb0ef41Sopenharmony_ci         d.InstructionSizeOfBuiltin(builtin);
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ciint OffHeapInstructionSize(HeapObject code, Builtin builtin) {
791cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
801cb0ef41Sopenharmony_ci  return d.InstructionSizeOfBuiltin(builtin);
811cb0ef41Sopenharmony_ci}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ciAddress OffHeapMetadataStart(HeapObject code, Builtin builtin) {
841cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
851cb0ef41Sopenharmony_ci  return d.MetadataStartOfBuiltin(builtin);
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ciAddress OffHeapMetadataEnd(HeapObject code, Builtin builtin) {
891cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
901cb0ef41Sopenharmony_ci  return d.MetadataStartOfBuiltin(builtin) + d.MetadataSizeOfBuiltin(builtin);
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciint OffHeapMetadataSize(HeapObject code, Builtin builtin) {
941cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
951cb0ef41Sopenharmony_ci  return d.MetadataSizeOfBuiltin(builtin);
961cb0ef41Sopenharmony_ci}
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ciAddress OffHeapSafepointTableAddress(HeapObject code, Builtin builtin) {
991cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1001cb0ef41Sopenharmony_ci  return d.SafepointTableStartOf(builtin);
1011cb0ef41Sopenharmony_ci}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ciint OffHeapSafepointTableSize(HeapObject code, Builtin builtin) {
1041cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1051cb0ef41Sopenharmony_ci  return d.SafepointTableSizeOf(builtin);
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ciAddress OffHeapHandlerTableAddress(HeapObject code, Builtin builtin) {
1091cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1101cb0ef41Sopenharmony_ci  return d.HandlerTableStartOf(builtin);
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciint OffHeapHandlerTableSize(HeapObject code, Builtin builtin) {
1141cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1151cb0ef41Sopenharmony_ci  return d.HandlerTableSizeOf(builtin);
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ciAddress OffHeapConstantPoolAddress(HeapObject code, Builtin builtin) {
1191cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1201cb0ef41Sopenharmony_ci  return d.ConstantPoolStartOf(builtin);
1211cb0ef41Sopenharmony_ci}
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ciint OffHeapConstantPoolSize(HeapObject code, Builtin builtin) {
1241cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1251cb0ef41Sopenharmony_ci  return d.ConstantPoolSizeOf(builtin);
1261cb0ef41Sopenharmony_ci}
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ciAddress OffHeapCodeCommentsAddress(HeapObject code, Builtin builtin) {
1291cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1301cb0ef41Sopenharmony_ci  return d.CodeCommentsStartOf(builtin);
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ciint OffHeapCodeCommentsSize(HeapObject code, Builtin builtin) {
1341cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1351cb0ef41Sopenharmony_ci  return d.CodeCommentsSizeOf(builtin);
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ciAddress OffHeapUnwindingInfoAddress(HeapObject code, Builtin builtin) {
1391cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1401cb0ef41Sopenharmony_ci  return d.UnwindingInfoStartOf(builtin);
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciint OffHeapUnwindingInfoSize(HeapObject code, Builtin builtin) {
1441cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedDataWithMaybeRemappedEmbeddedBuiltins(code);
1451cb0ef41Sopenharmony_ci  return d.UnwindingInfoSizeOf(builtin);
1461cb0ef41Sopenharmony_ci}
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_civoid Code::ClearEmbeddedObjects(Heap* heap) {
1491cb0ef41Sopenharmony_ci  HeapObject undefined = ReadOnlyRoots(heap).undefined_value();
1501cb0ef41Sopenharmony_ci  int mode_mask = RelocInfo::EmbeddedObjectModeMask();
1511cb0ef41Sopenharmony_ci  for (RelocIterator it(*this, mode_mask); !it.done(); it.next()) {
1521cb0ef41Sopenharmony_ci    DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()));
1531cb0ef41Sopenharmony_ci    it.rinfo()->set_target_object(heap, undefined, SKIP_WRITE_BARRIER);
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ci  set_embedded_objects_cleared(true);
1561cb0ef41Sopenharmony_ci}
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_civoid Code::Relocate(intptr_t delta) {
1591cb0ef41Sopenharmony_ci  for (RelocIterator it(*this, RelocInfo::kApplyMask); !it.done(); it.next()) {
1601cb0ef41Sopenharmony_ci    it.rinfo()->apply(delta);
1611cb0ef41Sopenharmony_ci  }
1621cb0ef41Sopenharmony_ci  FlushICache();
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_civoid Code::FlushICache() const {
1661cb0ef41Sopenharmony_ci  FlushInstructionCache(raw_instruction_start(), raw_instruction_size());
1671cb0ef41Sopenharmony_ci}
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_civoid Code::CopyFromNoFlush(ByteArray reloc_info, Heap* heap,
1701cb0ef41Sopenharmony_ci                           const CodeDesc& desc) {
1711cb0ef41Sopenharmony_ci  // Copy code.
1721cb0ef41Sopenharmony_ci  STATIC_ASSERT(kOnHeapBodyIsContiguous);
1731cb0ef41Sopenharmony_ci  CopyBytes(reinterpret_cast<byte*>(raw_instruction_start()), desc.buffer,
1741cb0ef41Sopenharmony_ci            static_cast<size_t>(desc.instr_size));
1751cb0ef41Sopenharmony_ci  // TODO(jgruber,v8:11036): Merge with the above.
1761cb0ef41Sopenharmony_ci  CopyBytes(reinterpret_cast<byte*>(raw_instruction_start() + desc.instr_size),
1771cb0ef41Sopenharmony_ci            desc.unwinding_info, static_cast<size_t>(desc.unwinding_info_size));
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  // Copy reloc info.
1801cb0ef41Sopenharmony_ci  CopyRelocInfoToByteArray(reloc_info, desc);
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  // Unbox handles and relocate.
1831cb0ef41Sopenharmony_ci  RelocateFromDesc(reloc_info, heap, desc);
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_civoid Code::RelocateFromDesc(ByteArray reloc_info, Heap* heap,
1871cb0ef41Sopenharmony_ci                            const CodeDesc& desc) {
1881cb0ef41Sopenharmony_ci  // Unbox handles and relocate.
1891cb0ef41Sopenharmony_ci  Assembler* origin = desc.origin;
1901cb0ef41Sopenharmony_ci  const int mode_mask = RelocInfo::PostCodegenRelocationMask();
1911cb0ef41Sopenharmony_ci  for (RelocIterator it(*this, reloc_info, mode_mask); !it.done(); it.next()) {
1921cb0ef41Sopenharmony_ci    RelocInfo::Mode mode = it.rinfo()->rmode();
1931cb0ef41Sopenharmony_ci    if (RelocInfo::IsEmbeddedObjectMode(mode)) {
1941cb0ef41Sopenharmony_ci      Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
1951cb0ef41Sopenharmony_ci      it.rinfo()->set_target_object(heap, *p, UPDATE_WRITE_BARRIER,
1961cb0ef41Sopenharmony_ci                                    SKIP_ICACHE_FLUSH);
1971cb0ef41Sopenharmony_ci    } else if (RelocInfo::IsCodeTargetMode(mode)) {
1981cb0ef41Sopenharmony_ci      // Rewrite code handles to direct pointers to the first instruction in the
1991cb0ef41Sopenharmony_ci      // code object.
2001cb0ef41Sopenharmony_ci      Handle<HeapObject> p = it.rinfo()->target_object_handle(origin);
2011cb0ef41Sopenharmony_ci      DCHECK(p->IsCodeT(GetPtrComprCageBaseSlow(*p)));
2021cb0ef41Sopenharmony_ci      Code code = FromCodeT(CodeT::cast(*p));
2031cb0ef41Sopenharmony_ci      it.rinfo()->set_target_address(code.raw_instruction_start(),
2041cb0ef41Sopenharmony_ci                                     UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
2051cb0ef41Sopenharmony_ci    } else if (RelocInfo::IsRuntimeEntry(mode)) {
2061cb0ef41Sopenharmony_ci      Address p = it.rinfo()->target_runtime_entry(origin);
2071cb0ef41Sopenharmony_ci      it.rinfo()->set_target_runtime_entry(p, UPDATE_WRITE_BARRIER,
2081cb0ef41Sopenharmony_ci                                           SKIP_ICACHE_FLUSH);
2091cb0ef41Sopenharmony_ci    } else {
2101cb0ef41Sopenharmony_ci      intptr_t delta =
2111cb0ef41Sopenharmony_ci          raw_instruction_start() - reinterpret_cast<Address>(desc.buffer);
2121cb0ef41Sopenharmony_ci      it.rinfo()->apply(delta);
2131cb0ef41Sopenharmony_ci    }
2141cb0ef41Sopenharmony_ci  }
2151cb0ef41Sopenharmony_ci}
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ciSafepointEntry Code::GetSafepointEntry(Isolate* isolate, Address pc) {
2181cb0ef41Sopenharmony_ci  SafepointTable table(isolate, pc, *this);
2191cb0ef41Sopenharmony_ci  return table.FindEntry(pc);
2201cb0ef41Sopenharmony_ci}
2211cb0ef41Sopenharmony_ci
2221cb0ef41Sopenharmony_ciAddress Code::OffHeapInstructionStart(Isolate* isolate, Address pc) const {
2231cb0ef41Sopenharmony_ci  DCHECK(is_off_heap_trampoline());
2241cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
2251cb0ef41Sopenharmony_ci  return d.InstructionStartOfBuiltin(builtin_id());
2261cb0ef41Sopenharmony_ci}
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ciAddress Code::OffHeapInstructionEnd(Isolate* isolate, Address pc) const {
2291cb0ef41Sopenharmony_ci  DCHECK(is_off_heap_trampoline());
2301cb0ef41Sopenharmony_ci  EmbeddedData d = EmbeddedData::GetEmbeddedDataForPC(isolate, pc);
2311cb0ef41Sopenharmony_ci  return d.InstructionStartOfBuiltin(builtin_id()) +
2321cb0ef41Sopenharmony_ci         d.InstructionSizeOfBuiltin(builtin_id());
2331cb0ef41Sopenharmony_ci}
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci// TODO(cbruni): Move to BytecodeArray
2361cb0ef41Sopenharmony_ciint AbstractCode::SourcePosition(int offset) {
2371cb0ef41Sopenharmony_ci  CHECK_NE(kind(), CodeKind::BASELINE);
2381cb0ef41Sopenharmony_ci  Object maybe_table = SourcePositionTableInternal();
2391cb0ef41Sopenharmony_ci  if (maybe_table.IsException()) return kNoSourcePosition;
2401cb0ef41Sopenharmony_ci
2411cb0ef41Sopenharmony_ci  ByteArray source_position_table = ByteArray::cast(maybe_table);
2421cb0ef41Sopenharmony_ci  // Subtract one because the current PC is one instruction after the call site.
2431cb0ef41Sopenharmony_ci  if (IsCode()) offset--;
2441cb0ef41Sopenharmony_ci  int position = 0;
2451cb0ef41Sopenharmony_ci  for (SourcePositionTableIterator iterator(
2461cb0ef41Sopenharmony_ci           source_position_table, SourcePositionTableIterator::kJavaScriptOnly,
2471cb0ef41Sopenharmony_ci           SourcePositionTableIterator::kDontSkipFunctionEntry);
2481cb0ef41Sopenharmony_ci       !iterator.done() && iterator.code_offset() <= offset;
2491cb0ef41Sopenharmony_ci       iterator.Advance()) {
2501cb0ef41Sopenharmony_ci    position = iterator.source_position().ScriptOffset();
2511cb0ef41Sopenharmony_ci  }
2521cb0ef41Sopenharmony_ci  return position;
2531cb0ef41Sopenharmony_ci}
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci// TODO(cbruni): Move to BytecodeArray
2561cb0ef41Sopenharmony_ciint AbstractCode::SourceStatementPosition(int offset) {
2571cb0ef41Sopenharmony_ci  CHECK_NE(kind(), CodeKind::BASELINE);
2581cb0ef41Sopenharmony_ci  // First find the closest position.
2591cb0ef41Sopenharmony_ci  int position = SourcePosition(offset);
2601cb0ef41Sopenharmony_ci  // Now find the closest statement position before the position.
2611cb0ef41Sopenharmony_ci  int statement_position = 0;
2621cb0ef41Sopenharmony_ci  for (SourcePositionTableIterator it(SourcePositionTableInternal());
2631cb0ef41Sopenharmony_ci       !it.done(); it.Advance()) {
2641cb0ef41Sopenharmony_ci    if (it.is_statement()) {
2651cb0ef41Sopenharmony_ci      int p = it.source_position().ScriptOffset();
2661cb0ef41Sopenharmony_ci      if (statement_position < p && p <= position) {
2671cb0ef41Sopenharmony_ci        statement_position = p;
2681cb0ef41Sopenharmony_ci      }
2691cb0ef41Sopenharmony_ci    }
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci  return statement_position;
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_cibool Code::CanDeoptAt(Isolate* isolate, Address pc) {
2751cb0ef41Sopenharmony_ci  DeoptimizationData deopt_data =
2761cb0ef41Sopenharmony_ci      DeoptimizationData::cast(deoptimization_data());
2771cb0ef41Sopenharmony_ci  Address code_start_address = InstructionStart(isolate, pc);
2781cb0ef41Sopenharmony_ci  for (int i = 0; i < deopt_data.DeoptCount(); i++) {
2791cb0ef41Sopenharmony_ci    if (deopt_data.Pc(i).value() == -1) continue;
2801cb0ef41Sopenharmony_ci    Address address = code_start_address + deopt_data.Pc(i).value();
2811cb0ef41Sopenharmony_ci    if (address == pc &&
2821cb0ef41Sopenharmony_ci        deopt_data.GetBytecodeOffset(i) != BytecodeOffset::None()) {
2831cb0ef41Sopenharmony_ci      return true;
2841cb0ef41Sopenharmony_ci    }
2851cb0ef41Sopenharmony_ci  }
2861cb0ef41Sopenharmony_ci  return false;
2871cb0ef41Sopenharmony_ci}
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_cibool Code::IsIsolateIndependent(Isolate* isolate) {
2901cb0ef41Sopenharmony_ci  static constexpr int kModeMask =
2911cb0ef41Sopenharmony_ci      RelocInfo::AllRealModesMask() &
2921cb0ef41Sopenharmony_ci      ~RelocInfo::ModeMask(RelocInfo::CONST_POOL) &
2931cb0ef41Sopenharmony_ci      ~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) &
2941cb0ef41Sopenharmony_ci      ~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
2951cb0ef41Sopenharmony_ci  STATIC_ASSERT(kModeMask ==
2961cb0ef41Sopenharmony_ci                (RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
2971cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
2981cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::COMPRESSED_EMBEDDED_OBJECT) |
2991cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) |
3001cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::DATA_EMBEDDED_OBJECT) |
3011cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
3021cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
3031cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
3041cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
3051cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
3061cb0ef41Sopenharmony_ci                 RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL)));
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci#if defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64) || \
3091cb0ef41Sopenharmony_ci    defined(V8_TARGET_ARCH_MIPS64)
3101cb0ef41Sopenharmony_ci  return RelocIterator(*this, kModeMask).done();
3111cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM64) || \
3121cb0ef41Sopenharmony_ci    defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS) ||    \
3131cb0ef41Sopenharmony_ci    defined(V8_TARGET_ARCH_S390) || defined(V8_TARGET_ARCH_IA32) ||   \
3141cb0ef41Sopenharmony_ci    defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_LOONG64)
3151cb0ef41Sopenharmony_ci  for (RelocIterator it(*this, kModeMask); !it.done(); it.next()) {
3161cb0ef41Sopenharmony_ci    // On these platforms we emit relative builtin-to-builtin
3171cb0ef41Sopenharmony_ci    // jumps for isolate independent builtins in the snapshot. They are later
3181cb0ef41Sopenharmony_ci    // rewritten as pc-relative jumps to the off-heap instruction stream and are
3191cb0ef41Sopenharmony_ci    // thus process-independent. See also: FinalizeEmbeddedCodeTargets.
3201cb0ef41Sopenharmony_ci    if (RelocInfo::IsCodeTargetMode(it.rinfo()->rmode())) {
3211cb0ef41Sopenharmony_ci      Address target_address = it.rinfo()->target_address();
3221cb0ef41Sopenharmony_ci      if (OffHeapInstructionStream::PcIsOffHeap(isolate, target_address))
3231cb0ef41Sopenharmony_ci        continue;
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci      Code target = Code::GetCodeFromTargetAddress(target_address);
3261cb0ef41Sopenharmony_ci      CHECK(target.IsCode());
3271cb0ef41Sopenharmony_ci      if (Builtins::IsIsolateIndependentBuiltin(target)) continue;
3281cb0ef41Sopenharmony_ci    }
3291cb0ef41Sopenharmony_ci    return false;
3301cb0ef41Sopenharmony_ci  }
3311cb0ef41Sopenharmony_ci  return true;
3321cb0ef41Sopenharmony_ci#else
3331cb0ef41Sopenharmony_ci#error Unsupported architecture.
3341cb0ef41Sopenharmony_ci#endif
3351cb0ef41Sopenharmony_ci}
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_cibool Code::Inlines(SharedFunctionInfo sfi) {
3381cb0ef41Sopenharmony_ci  // We can only check for inlining for optimized code.
3391cb0ef41Sopenharmony_ci  DCHECK(is_optimized_code());
3401cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
3411cb0ef41Sopenharmony_ci  DeoptimizationData const data =
3421cb0ef41Sopenharmony_ci      DeoptimizationData::cast(deoptimization_data());
3431cb0ef41Sopenharmony_ci  if (data.length() == 0) return false;
3441cb0ef41Sopenharmony_ci  if (data.SharedFunctionInfo() == sfi) return true;
3451cb0ef41Sopenharmony_ci  DeoptimizationLiteralArray const literals = data.LiteralArray();
3461cb0ef41Sopenharmony_ci  int const inlined_count = data.InlinedFunctionCount().value();
3471cb0ef41Sopenharmony_ci  for (int i = 0; i < inlined_count; ++i) {
3481cb0ef41Sopenharmony_ci    if (SharedFunctionInfo::cast(literals.get(i)) == sfi) return true;
3491cb0ef41Sopenharmony_ci  }
3501cb0ef41Sopenharmony_ci  return false;
3511cb0ef41Sopenharmony_ci}
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ciCode::OptimizedCodeIterator::OptimizedCodeIterator(Isolate* isolate) {
3541cb0ef41Sopenharmony_ci  isolate_ = isolate;
3551cb0ef41Sopenharmony_ci  Object list = isolate->heap()->native_contexts_list();
3561cb0ef41Sopenharmony_ci  next_context_ =
3571cb0ef41Sopenharmony_ci      list.IsUndefined(isolate_) ? NativeContext() : NativeContext::cast(list);
3581cb0ef41Sopenharmony_ci}
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ciCode Code::OptimizedCodeIterator::Next() {
3611cb0ef41Sopenharmony_ci  do {
3621cb0ef41Sopenharmony_ci    Object next;
3631cb0ef41Sopenharmony_ci    if (!current_code_.is_null()) {
3641cb0ef41Sopenharmony_ci      // Get next code in the linked list.
3651cb0ef41Sopenharmony_ci      next = current_code_.next_code_link();
3661cb0ef41Sopenharmony_ci    } else if (!next_context_.is_null()) {
3671cb0ef41Sopenharmony_ci      // Linked list of code exhausted. Get list of next context.
3681cb0ef41Sopenharmony_ci      next = next_context_.OptimizedCodeListHead();
3691cb0ef41Sopenharmony_ci      Object next_context = next_context_.next_context_link();
3701cb0ef41Sopenharmony_ci      next_context_ = next_context.IsUndefined(isolate_)
3711cb0ef41Sopenharmony_ci                          ? NativeContext()
3721cb0ef41Sopenharmony_ci                          : NativeContext::cast(next_context);
3731cb0ef41Sopenharmony_ci    } else {
3741cb0ef41Sopenharmony_ci      // Exhausted contexts.
3751cb0ef41Sopenharmony_ci      return Code();
3761cb0ef41Sopenharmony_ci    }
3771cb0ef41Sopenharmony_ci    current_code_ =
3781cb0ef41Sopenharmony_ci        next.IsUndefined(isolate_) ? Code() : FromCodeT(CodeT::cast(next));
3791cb0ef41Sopenharmony_ci  } while (current_code_.is_null());
3801cb0ef41Sopenharmony_ci  DCHECK(CodeKindCanDeoptimize(current_code_.kind()));
3811cb0ef41Sopenharmony_ci  return current_code_;
3821cb0ef41Sopenharmony_ci}
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ciHandle<DeoptimizationData> DeoptimizationData::New(Isolate* isolate,
3851cb0ef41Sopenharmony_ci                                                   int deopt_entry_count,
3861cb0ef41Sopenharmony_ci                                                   AllocationType allocation) {
3871cb0ef41Sopenharmony_ci  return Handle<DeoptimizationData>::cast(isolate->factory()->NewFixedArray(
3881cb0ef41Sopenharmony_ci      LengthFor(deopt_entry_count), allocation));
3891cb0ef41Sopenharmony_ci}
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ciHandle<DeoptimizationData> DeoptimizationData::Empty(Isolate* isolate) {
3921cb0ef41Sopenharmony_ci  return Handle<DeoptimizationData>::cast(
3931cb0ef41Sopenharmony_ci      isolate->factory()->empty_fixed_array());
3941cb0ef41Sopenharmony_ci}
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ciSharedFunctionInfo DeoptimizationData::GetInlinedFunction(int index) {
3971cb0ef41Sopenharmony_ci  if (index == -1) {
3981cb0ef41Sopenharmony_ci    return SharedFunctionInfo::cast(SharedFunctionInfo());
3991cb0ef41Sopenharmony_ci  } else {
4001cb0ef41Sopenharmony_ci    return SharedFunctionInfo::cast(LiteralArray().get(index));
4011cb0ef41Sopenharmony_ci  }
4021cb0ef41Sopenharmony_ci}
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_ciconst char* Code::GetName(Isolate* isolate) const {
4071cb0ef41Sopenharmony_ci  if (kind() == CodeKind::BYTECODE_HANDLER) {
4081cb0ef41Sopenharmony_ci    return isolate->interpreter()->LookupNameOfBytecodeHandler(*this);
4091cb0ef41Sopenharmony_ci  } else {
4101cb0ef41Sopenharmony_ci    // There are some handlers and ICs that we can also find names for with
4111cb0ef41Sopenharmony_ci    // Builtins::Lookup.
4121cb0ef41Sopenharmony_ci    return isolate->builtins()->Lookup(raw_instruction_start());
4131cb0ef41Sopenharmony_ci  }
4141cb0ef41Sopenharmony_ci}
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_cinamespace {
4171cb0ef41Sopenharmony_civoid print_pc(std::ostream& os, int pc) {
4181cb0ef41Sopenharmony_ci  if (pc == -1) {
4191cb0ef41Sopenharmony_ci    os << "NA";
4201cb0ef41Sopenharmony_ci  } else {
4211cb0ef41Sopenharmony_ci    os << std::hex << pc << std::dec;
4221cb0ef41Sopenharmony_ci  }
4231cb0ef41Sopenharmony_ci}
4241cb0ef41Sopenharmony_ci}  // anonymous namespace
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_civoid DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) {
4271cb0ef41Sopenharmony_ci  if (length() == 0) {
4281cb0ef41Sopenharmony_ci    os << "Deoptimization Input Data invalidated by lazy deoptimization\n";
4291cb0ef41Sopenharmony_ci    return;
4301cb0ef41Sopenharmony_ci  }
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci  int const inlined_function_count = InlinedFunctionCount().value();
4331cb0ef41Sopenharmony_ci  os << "Inlined functions (count = " << inlined_function_count << ")\n";
4341cb0ef41Sopenharmony_ci  for (int id = 0; id < inlined_function_count; ++id) {
4351cb0ef41Sopenharmony_ci    Object info = LiteralArray().get(id);
4361cb0ef41Sopenharmony_ci    os << " " << Brief(SharedFunctionInfo::cast(info)) << "\n";
4371cb0ef41Sopenharmony_ci  }
4381cb0ef41Sopenharmony_ci  os << "\n";
4391cb0ef41Sopenharmony_ci  int deopt_count = DeoptCount();
4401cb0ef41Sopenharmony_ci  os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
4411cb0ef41Sopenharmony_ci  if (0 != deopt_count) {
4421cb0ef41Sopenharmony_ci#ifdef DEBUG
4431cb0ef41Sopenharmony_ci    os << " index  bytecode-offset  node-id    pc";
4441cb0ef41Sopenharmony_ci#else   // DEBUG
4451cb0ef41Sopenharmony_ci    os << " index  bytecode-offset    pc";
4461cb0ef41Sopenharmony_ci#endif  // DEBUG
4471cb0ef41Sopenharmony_ci    if (FLAG_print_code_verbose) os << "  commands";
4481cb0ef41Sopenharmony_ci    os << "\n";
4491cb0ef41Sopenharmony_ci  }
4501cb0ef41Sopenharmony_ci  for (int i = 0; i < deopt_count; i++) {
4511cb0ef41Sopenharmony_ci    os << std::setw(6) << i << "  " << std::setw(15)
4521cb0ef41Sopenharmony_ci       << GetBytecodeOffset(i).ToInt() << "  "
4531cb0ef41Sopenharmony_ci#ifdef DEBUG
4541cb0ef41Sopenharmony_ci       << std::setw(7) << NodeId(i).value() << "  "
4551cb0ef41Sopenharmony_ci#endif  // DEBUG
4561cb0ef41Sopenharmony_ci       << std::setw(4);
4571cb0ef41Sopenharmony_ci    print_pc(os, Pc(i).value());
4581cb0ef41Sopenharmony_ci    os << std::setw(2);
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_ci    if (!FLAG_print_code_verbose) {
4611cb0ef41Sopenharmony_ci      os << "\n";
4621cb0ef41Sopenharmony_ci      continue;
4631cb0ef41Sopenharmony_ci    }
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci    TranslationArrayPrintSingleFrame(os, TranslationByteArray(),
4661cb0ef41Sopenharmony_ci                                     TranslationIndex(i).value(),
4671cb0ef41Sopenharmony_ci                                     LiteralArray());
4681cb0ef41Sopenharmony_ci  }
4691cb0ef41Sopenharmony_ci}
4701cb0ef41Sopenharmony_ci
4711cb0ef41Sopenharmony_cinamespace {
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ciinline void DisassembleCodeRange(Isolate* isolate, std::ostream& os, Code code,
4741cb0ef41Sopenharmony_ci                                 Address begin, size_t size,
4751cb0ef41Sopenharmony_ci                                 Address current_pc) {
4761cb0ef41Sopenharmony_ci  Address end = begin + size;
4771cb0ef41Sopenharmony_ci  AllowHandleAllocation allow_handles;
4781cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
4791cb0ef41Sopenharmony_ci  HandleScope handle_scope(isolate);
4801cb0ef41Sopenharmony_ci  Disassembler::Decode(isolate, os, reinterpret_cast<byte*>(begin),
4811cb0ef41Sopenharmony_ci                       reinterpret_cast<byte*>(end),
4821cb0ef41Sopenharmony_ci                       CodeReference(handle(code, isolate)), current_pc);
4831cb0ef41Sopenharmony_ci}
4841cb0ef41Sopenharmony_ci
4851cb0ef41Sopenharmony_ci}  // namespace
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_civoid Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
4881cb0ef41Sopenharmony_ci                       Address current_pc) {
4891cb0ef41Sopenharmony_ci  os << "kind = " << CodeKindToString(kind()) << "\n";
4901cb0ef41Sopenharmony_ci  if (name == nullptr) {
4911cb0ef41Sopenharmony_ci    name = GetName(isolate);
4921cb0ef41Sopenharmony_ci  }
4931cb0ef41Sopenharmony_ci  if ((name != nullptr) && (name[0] != '\0')) {
4941cb0ef41Sopenharmony_ci    os << "name = " << name << "\n";
4951cb0ef41Sopenharmony_ci  }
4961cb0ef41Sopenharmony_ci  if (CodeKindIsOptimizedJSFunction(kind()) && kind() != CodeKind::BASELINE) {
4971cb0ef41Sopenharmony_ci    os << "stack_slots = " << stack_slots() << "\n";
4981cb0ef41Sopenharmony_ci  }
4991cb0ef41Sopenharmony_ci  os << "compiler = "
5001cb0ef41Sopenharmony_ci     << (is_turbofanned()
5011cb0ef41Sopenharmony_ci             ? "turbofan"
5021cb0ef41Sopenharmony_ci             : is_maglevved()
5031cb0ef41Sopenharmony_ci                   ? "turbofan"
5041cb0ef41Sopenharmony_ci                   : kind() == CodeKind::BASELINE ? "baseline" : "unknown")
5051cb0ef41Sopenharmony_ci     << "\n";
5061cb0ef41Sopenharmony_ci  os << "address = " << reinterpret_cast<void*>(ptr()) << "\n\n";
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  if (is_off_heap_trampoline()) {
5091cb0ef41Sopenharmony_ci    int trampoline_size = raw_instruction_size();
5101cb0ef41Sopenharmony_ci    os << "Trampoline (size = " << trampoline_size << ")\n";
5111cb0ef41Sopenharmony_ci    DisassembleCodeRange(isolate, os, *this, raw_instruction_start(),
5121cb0ef41Sopenharmony_ci                         trampoline_size, current_pc);
5131cb0ef41Sopenharmony_ci    os << "\n";
5141cb0ef41Sopenharmony_ci  }
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci  {
5171cb0ef41Sopenharmony_ci    int code_size = InstructionSize();
5181cb0ef41Sopenharmony_ci    os << "Instructions (size = " << code_size << ")\n";
5191cb0ef41Sopenharmony_ci    DisassembleCodeRange(isolate, os, *this, InstructionStart(), code_size,
5201cb0ef41Sopenharmony_ci                         current_pc);
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci    if (int pool_size = constant_pool_size()) {
5231cb0ef41Sopenharmony_ci      DCHECK_EQ(pool_size & kPointerAlignmentMask, 0);
5241cb0ef41Sopenharmony_ci      os << "\nConstant Pool (size = " << pool_size << ")\n";
5251cb0ef41Sopenharmony_ci      base::Vector<char> buf = base::Vector<char>::New(50);
5261cb0ef41Sopenharmony_ci      intptr_t* ptr = reinterpret_cast<intptr_t*>(constant_pool());
5271cb0ef41Sopenharmony_ci      for (int i = 0; i < pool_size; i += kSystemPointerSize, ptr++) {
5281cb0ef41Sopenharmony_ci        SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
5291cb0ef41Sopenharmony_ci        os << static_cast<const void*>(ptr) << "  " << buf.begin() << "\n";
5301cb0ef41Sopenharmony_ci      }
5311cb0ef41Sopenharmony_ci    }
5321cb0ef41Sopenharmony_ci  }
5331cb0ef41Sopenharmony_ci  os << "\n";
5341cb0ef41Sopenharmony_ci
5351cb0ef41Sopenharmony_ci  // TODO(cbruni): add support for baseline code.
5361cb0ef41Sopenharmony_ci  if (kind() != CodeKind::BASELINE) {
5371cb0ef41Sopenharmony_ci    {
5381cb0ef41Sopenharmony_ci      SourcePositionTableIterator it(
5391cb0ef41Sopenharmony_ci          source_position_table(),
5401cb0ef41Sopenharmony_ci          SourcePositionTableIterator::kJavaScriptOnly);
5411cb0ef41Sopenharmony_ci      if (!it.done()) {
5421cb0ef41Sopenharmony_ci        os << "Source positions:\n pc offset  position\n";
5431cb0ef41Sopenharmony_ci        for (; !it.done(); it.Advance()) {
5441cb0ef41Sopenharmony_ci          os << std::setw(10) << std::hex << it.code_offset() << std::dec
5451cb0ef41Sopenharmony_ci             << std::setw(10) << it.source_position().ScriptOffset()
5461cb0ef41Sopenharmony_ci             << (it.is_statement() ? "  statement" : "") << "\n";
5471cb0ef41Sopenharmony_ci        }
5481cb0ef41Sopenharmony_ci        os << "\n";
5491cb0ef41Sopenharmony_ci      }
5501cb0ef41Sopenharmony_ci    }
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ci    {
5531cb0ef41Sopenharmony_ci      SourcePositionTableIterator it(
5541cb0ef41Sopenharmony_ci          source_position_table(), SourcePositionTableIterator::kExternalOnly);
5551cb0ef41Sopenharmony_ci      if (!it.done()) {
5561cb0ef41Sopenharmony_ci        os << "External Source positions:\n pc offset  fileid  line\n";
5571cb0ef41Sopenharmony_ci        for (; !it.done(); it.Advance()) {
5581cb0ef41Sopenharmony_ci          DCHECK(it.source_position().IsExternal());
5591cb0ef41Sopenharmony_ci          os << std::setw(10) << std::hex << it.code_offset() << std::dec
5601cb0ef41Sopenharmony_ci             << std::setw(10) << it.source_position().ExternalFileId()
5611cb0ef41Sopenharmony_ci             << std::setw(10) << it.source_position().ExternalLine() << "\n";
5621cb0ef41Sopenharmony_ci        }
5631cb0ef41Sopenharmony_ci        os << "\n";
5641cb0ef41Sopenharmony_ci      }
5651cb0ef41Sopenharmony_ci    }
5661cb0ef41Sopenharmony_ci  }
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  if (CodeKindCanDeoptimize(kind())) {
5691cb0ef41Sopenharmony_ci    DeoptimizationData data =
5701cb0ef41Sopenharmony_ci        DeoptimizationData::cast(this->deoptimization_data());
5711cb0ef41Sopenharmony_ci    data.DeoptimizationDataPrint(os);
5721cb0ef41Sopenharmony_ci  }
5731cb0ef41Sopenharmony_ci  os << "\n";
5741cb0ef41Sopenharmony_ci
5751cb0ef41Sopenharmony_ci  if (uses_safepoint_table()) {
5761cb0ef41Sopenharmony_ci    SafepointTable table(isolate, current_pc, *this);
5771cb0ef41Sopenharmony_ci    table.Print(os);
5781cb0ef41Sopenharmony_ci    os << "\n";
5791cb0ef41Sopenharmony_ci  }
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci  if (has_handler_table()) {
5821cb0ef41Sopenharmony_ci    HandlerTable table(*this);
5831cb0ef41Sopenharmony_ci    os << "Handler Table (size = " << table.NumberOfReturnEntries() << ")\n";
5841cb0ef41Sopenharmony_ci    if (CodeKindIsOptimizedJSFunction(kind())) {
5851cb0ef41Sopenharmony_ci      table.HandlerTableReturnPrint(os);
5861cb0ef41Sopenharmony_ci    }
5871cb0ef41Sopenharmony_ci    os << "\n";
5881cb0ef41Sopenharmony_ci  }
5891cb0ef41Sopenharmony_ci
5901cb0ef41Sopenharmony_ci  os << "RelocInfo (size = " << relocation_size() << ")\n";
5911cb0ef41Sopenharmony_ci  for (RelocIterator it(*this); !it.done(); it.next()) {
5921cb0ef41Sopenharmony_ci    it.rinfo()->Print(isolate, os);
5931cb0ef41Sopenharmony_ci  }
5941cb0ef41Sopenharmony_ci  os << "\n";
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci  if (has_unwinding_info()) {
5971cb0ef41Sopenharmony_ci    os << "UnwindingInfo (size = " << unwinding_info_size() << ")\n";
5981cb0ef41Sopenharmony_ci    EhFrameDisassembler eh_frame_disassembler(
5991cb0ef41Sopenharmony_ci        reinterpret_cast<byte*>(unwinding_info_start()),
6001cb0ef41Sopenharmony_ci        reinterpret_cast<byte*>(unwinding_info_end()));
6011cb0ef41Sopenharmony_ci    eh_frame_disassembler.DisassembleToStream(os);
6021cb0ef41Sopenharmony_ci    os << "\n";
6031cb0ef41Sopenharmony_ci  }
6041cb0ef41Sopenharmony_ci}
6051cb0ef41Sopenharmony_ci#endif  // ENABLE_DISASSEMBLER
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_civoid BytecodeArray::Disassemble(std::ostream& os) {
6081cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci  os << "Parameter count " << parameter_count() << "\n";
6111cb0ef41Sopenharmony_ci  os << "Register count " << register_count() << "\n";
6121cb0ef41Sopenharmony_ci  os << "Frame size " << frame_size() << "\n";
6131cb0ef41Sopenharmony_ci  os << "OSR urgency: " << osr_urgency() << "\n";
6141cb0ef41Sopenharmony_ci  os << "Bytecode age: " << bytecode_age() << "\n";
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci  Address base_address = GetFirstBytecodeAddress();
6171cb0ef41Sopenharmony_ci  SourcePositionTableIterator source_positions(SourcePositionTable());
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci  // Storage for backing the handle passed to the iterator. This handle won't be
6201cb0ef41Sopenharmony_ci  // updated by the gc, but that's ok because we've disallowed GCs anyway.
6211cb0ef41Sopenharmony_ci  BytecodeArray handle_storage = *this;
6221cb0ef41Sopenharmony_ci  Handle<BytecodeArray> handle(reinterpret_cast<Address*>(&handle_storage));
6231cb0ef41Sopenharmony_ci  interpreter::BytecodeArrayIterator iterator(handle);
6241cb0ef41Sopenharmony_ci  while (!iterator.done()) {
6251cb0ef41Sopenharmony_ci    if (!source_positions.done() &&
6261cb0ef41Sopenharmony_ci        iterator.current_offset() == source_positions.code_offset()) {
6271cb0ef41Sopenharmony_ci      os << std::setw(5) << source_positions.source_position().ScriptOffset();
6281cb0ef41Sopenharmony_ci      os << (source_positions.is_statement() ? " S> " : " E> ");
6291cb0ef41Sopenharmony_ci      source_positions.Advance();
6301cb0ef41Sopenharmony_ci    } else {
6311cb0ef41Sopenharmony_ci      os << "         ";
6321cb0ef41Sopenharmony_ci    }
6331cb0ef41Sopenharmony_ci    Address current_address = base_address + iterator.current_offset();
6341cb0ef41Sopenharmony_ci    os << reinterpret_cast<const void*>(current_address) << " @ "
6351cb0ef41Sopenharmony_ci       << std::setw(4) << iterator.current_offset() << " : ";
6361cb0ef41Sopenharmony_ci    interpreter::BytecodeDecoder::Decode(
6371cb0ef41Sopenharmony_ci        os, reinterpret_cast<byte*>(current_address));
6381cb0ef41Sopenharmony_ci    if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
6391cb0ef41Sopenharmony_ci      Address jump_target = base_address + iterator.GetJumpTargetOffset();
6401cb0ef41Sopenharmony_ci      os << " (" << reinterpret_cast<void*>(jump_target) << " @ "
6411cb0ef41Sopenharmony_ci         << iterator.GetJumpTargetOffset() << ")";
6421cb0ef41Sopenharmony_ci    }
6431cb0ef41Sopenharmony_ci    if (interpreter::Bytecodes::IsSwitch(iterator.current_bytecode())) {
6441cb0ef41Sopenharmony_ci      os << " {";
6451cb0ef41Sopenharmony_ci      bool first_entry = true;
6461cb0ef41Sopenharmony_ci      for (interpreter::JumpTableTargetOffset entry :
6471cb0ef41Sopenharmony_ci           iterator.GetJumpTableTargetOffsets()) {
6481cb0ef41Sopenharmony_ci        if (first_entry) {
6491cb0ef41Sopenharmony_ci          first_entry = false;
6501cb0ef41Sopenharmony_ci        } else {
6511cb0ef41Sopenharmony_ci          os << ",";
6521cb0ef41Sopenharmony_ci        }
6531cb0ef41Sopenharmony_ci        os << " " << entry.case_value << ": @" << entry.target_offset;
6541cb0ef41Sopenharmony_ci      }
6551cb0ef41Sopenharmony_ci      os << " }";
6561cb0ef41Sopenharmony_ci    }
6571cb0ef41Sopenharmony_ci    os << std::endl;
6581cb0ef41Sopenharmony_ci    iterator.Advance();
6591cb0ef41Sopenharmony_ci  }
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci  os << "Constant pool (size = " << constant_pool().length() << ")\n";
6621cb0ef41Sopenharmony_ci#ifdef OBJECT_PRINT
6631cb0ef41Sopenharmony_ci  if (constant_pool().length() > 0) {
6641cb0ef41Sopenharmony_ci    constant_pool().Print(os);
6651cb0ef41Sopenharmony_ci  }
6661cb0ef41Sopenharmony_ci#endif
6671cb0ef41Sopenharmony_ci
6681cb0ef41Sopenharmony_ci  os << "Handler Table (size = " << handler_table().length() << ")\n";
6691cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
6701cb0ef41Sopenharmony_ci  if (handler_table().length() > 0) {
6711cb0ef41Sopenharmony_ci    HandlerTable table(*this);
6721cb0ef41Sopenharmony_ci    table.HandlerTableRangePrint(os);
6731cb0ef41Sopenharmony_ci  }
6741cb0ef41Sopenharmony_ci#endif
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ci  ByteArray source_position_table = SourcePositionTable();
6771cb0ef41Sopenharmony_ci  os << "Source Position Table (size = " << source_position_table.length()
6781cb0ef41Sopenharmony_ci     << ")\n";
6791cb0ef41Sopenharmony_ci#ifdef OBJECT_PRINT
6801cb0ef41Sopenharmony_ci  if (source_position_table.length() > 0) {
6811cb0ef41Sopenharmony_ci    os << Brief(source_position_table) << std::endl;
6821cb0ef41Sopenharmony_ci  }
6831cb0ef41Sopenharmony_ci#endif
6841cb0ef41Sopenharmony_ci}
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_civoid BytecodeArray::CopyBytecodesTo(BytecodeArray to) {
6871cb0ef41Sopenharmony_ci  BytecodeArray from = *this;
6881cb0ef41Sopenharmony_ci  DCHECK_EQ(from.length(), to.length());
6891cb0ef41Sopenharmony_ci  CopyBytes(reinterpret_cast<byte*>(to.GetFirstBytecodeAddress()),
6901cb0ef41Sopenharmony_ci            reinterpret_cast<byte*>(from.GetFirstBytecodeAddress()),
6911cb0ef41Sopenharmony_ci            from.length());
6921cb0ef41Sopenharmony_ci}
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_civoid BytecodeArray::MakeOlder() {
6951cb0ef41Sopenharmony_ci  // BytecodeArray is aged in concurrent marker.
6961cb0ef41Sopenharmony_ci  // The word must be completely within the byte code array.
6971cb0ef41Sopenharmony_ci  Address age_addr = address() + kBytecodeAgeOffset;
6981cb0ef41Sopenharmony_ci  DCHECK_LE(RoundDown(age_addr, kTaggedSize) + kTaggedSize, address() + Size());
6991cb0ef41Sopenharmony_ci  Age age = bytecode_age();
7001cb0ef41Sopenharmony_ci  if (age < kLastBytecodeAge) {
7011cb0ef41Sopenharmony_ci    static_assert(kBytecodeAgeSize == kUInt16Size);
7021cb0ef41Sopenharmony_ci    base::AsAtomic16::Relaxed_CompareAndSwap(
7031cb0ef41Sopenharmony_ci        reinterpret_cast<base::Atomic16*>(age_addr), age, age + 1);
7041cb0ef41Sopenharmony_ci  }
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ci  DCHECK_GE(bytecode_age(), kFirstBytecodeAge);
7071cb0ef41Sopenharmony_ci  DCHECK_LE(bytecode_age(), kLastBytecodeAge);
7081cb0ef41Sopenharmony_ci}
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_cibool BytecodeArray::IsOld() const {
7111cb0ef41Sopenharmony_ci  return bytecode_age() >= kIsOldBytecodeAge;
7121cb0ef41Sopenharmony_ci}
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ciDependentCode DependentCode::GetDependentCode(Handle<HeapObject> object) {
7151cb0ef41Sopenharmony_ci  if (object->IsMap()) {
7161cb0ef41Sopenharmony_ci    return Handle<Map>::cast(object)->dependent_code();
7171cb0ef41Sopenharmony_ci  } else if (object->IsPropertyCell()) {
7181cb0ef41Sopenharmony_ci    return Handle<PropertyCell>::cast(object)->dependent_code();
7191cb0ef41Sopenharmony_ci  } else if (object->IsAllocationSite()) {
7201cb0ef41Sopenharmony_ci    return Handle<AllocationSite>::cast(object)->dependent_code();
7211cb0ef41Sopenharmony_ci  }
7221cb0ef41Sopenharmony_ci  UNREACHABLE();
7231cb0ef41Sopenharmony_ci}
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_civoid DependentCode::SetDependentCode(Handle<HeapObject> object,
7261cb0ef41Sopenharmony_ci                                     Handle<DependentCode> dep) {
7271cb0ef41Sopenharmony_ci  if (object->IsMap()) {
7281cb0ef41Sopenharmony_ci    Handle<Map>::cast(object)->set_dependent_code(*dep);
7291cb0ef41Sopenharmony_ci  } else if (object->IsPropertyCell()) {
7301cb0ef41Sopenharmony_ci    Handle<PropertyCell>::cast(object)->set_dependent_code(*dep);
7311cb0ef41Sopenharmony_ci  } else if (object->IsAllocationSite()) {
7321cb0ef41Sopenharmony_ci    Handle<AllocationSite>::cast(object)->set_dependent_code(*dep);
7331cb0ef41Sopenharmony_ci  } else {
7341cb0ef41Sopenharmony_ci    UNREACHABLE();
7351cb0ef41Sopenharmony_ci  }
7361cb0ef41Sopenharmony_ci}
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_cinamespace {
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_civoid PrintDependencyGroups(DependentCode::DependencyGroups groups) {
7411cb0ef41Sopenharmony_ci  while (groups != 0) {
7421cb0ef41Sopenharmony_ci    auto group = static_cast<DependentCode::DependencyGroup>(
7431cb0ef41Sopenharmony_ci        1 << base::bits::CountTrailingZeros(static_cast<uint32_t>(groups)));
7441cb0ef41Sopenharmony_ci    StdoutStream{} << DependentCode::DependencyGroupName(group);
7451cb0ef41Sopenharmony_ci    groups &= ~group;
7461cb0ef41Sopenharmony_ci    if (groups != 0) StdoutStream{} << ",";
7471cb0ef41Sopenharmony_ci  }
7481cb0ef41Sopenharmony_ci}
7491cb0ef41Sopenharmony_ci
7501cb0ef41Sopenharmony_ci}  // namespace
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_civoid DependentCode::InstallDependency(Isolate* isolate, Handle<Code> code,
7531cb0ef41Sopenharmony_ci                                      Handle<HeapObject> object,
7541cb0ef41Sopenharmony_ci                                      DependencyGroups groups) {
7551cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(FLAG_trace_compilation_dependencies)) {
7561cb0ef41Sopenharmony_ci    StdoutStream{} << "Installing dependency of [" << code->GetHeapObject()
7571cb0ef41Sopenharmony_ci                   << "] on [" << object << "] in groups [";
7581cb0ef41Sopenharmony_ci    PrintDependencyGroups(groups);
7591cb0ef41Sopenharmony_ci    StdoutStream{} << "]\n";
7601cb0ef41Sopenharmony_ci  }
7611cb0ef41Sopenharmony_ci  Handle<DependentCode> old_deps(DependentCode::GetDependentCode(object),
7621cb0ef41Sopenharmony_ci                                 isolate);
7631cb0ef41Sopenharmony_ci  Handle<DependentCode> new_deps =
7641cb0ef41Sopenharmony_ci      InsertWeakCode(isolate, old_deps, groups, code);
7651cb0ef41Sopenharmony_ci
7661cb0ef41Sopenharmony_ci  // Update the list head if necessary.
7671cb0ef41Sopenharmony_ci  if (!new_deps.is_identical_to(old_deps)) {
7681cb0ef41Sopenharmony_ci    DependentCode::SetDependentCode(object, new_deps);
7691cb0ef41Sopenharmony_ci  }
7701cb0ef41Sopenharmony_ci}
7711cb0ef41Sopenharmony_ci
7721cb0ef41Sopenharmony_ciHandle<DependentCode> DependentCode::InsertWeakCode(
7731cb0ef41Sopenharmony_ci    Isolate* isolate, Handle<DependentCode> entries, DependencyGroups groups,
7741cb0ef41Sopenharmony_ci    Handle<Code> code) {
7751cb0ef41Sopenharmony_ci  if (entries->length() == entries->capacity()) {
7761cb0ef41Sopenharmony_ci    // We'd have to grow - try to compact first.
7771cb0ef41Sopenharmony_ci    entries->IterateAndCompact([](CodeT, DependencyGroups) { return false; });
7781cb0ef41Sopenharmony_ci  }
7791cb0ef41Sopenharmony_ci
7801cb0ef41Sopenharmony_ci  MaybeObjectHandle code_slot(HeapObjectReference::Weak(ToCodeT(*code)),
7811cb0ef41Sopenharmony_ci                              isolate);
7821cb0ef41Sopenharmony_ci  MaybeObjectHandle group_slot(MaybeObject::FromSmi(Smi::FromInt(groups)),
7831cb0ef41Sopenharmony_ci                               isolate);
7841cb0ef41Sopenharmony_ci  entries = Handle<DependentCode>::cast(
7851cb0ef41Sopenharmony_ci      WeakArrayList::AddToEnd(isolate, entries, code_slot, group_slot));
7861cb0ef41Sopenharmony_ci  return entries;
7871cb0ef41Sopenharmony_ci}
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ciHandle<DependentCode> DependentCode::New(Isolate* isolate,
7901cb0ef41Sopenharmony_ci                                         DependencyGroups groups,
7911cb0ef41Sopenharmony_ci                                         Handle<Code> code) {
7921cb0ef41Sopenharmony_ci  Handle<DependentCode> result = Handle<DependentCode>::cast(
7931cb0ef41Sopenharmony_ci      isolate->factory()->NewWeakArrayList(LengthFor(1), AllocationType::kOld));
7941cb0ef41Sopenharmony_ci  result->Set(0, HeapObjectReference::Weak(ToCodeT(*code)));
7951cb0ef41Sopenharmony_ci  result->Set(1, Smi::FromInt(groups));
7961cb0ef41Sopenharmony_ci  return result;
7971cb0ef41Sopenharmony_ci}
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_civoid DependentCode::IterateAndCompact(const IterateAndCompactFn& fn) {
8001cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8011cb0ef41Sopenharmony_ci
8021cb0ef41Sopenharmony_ci  int len = length();
8031cb0ef41Sopenharmony_ci  if (len == 0) return;
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_ci  // We compact during traversal, thus use a somewhat custom loop construct:
8061cb0ef41Sopenharmony_ci  //
8071cb0ef41Sopenharmony_ci  // - Loop back-to-front s.t. trailing cleared entries can simply drop off
8081cb0ef41Sopenharmony_ci  //   the back of the list.
8091cb0ef41Sopenharmony_ci  // - Any cleared slots are filled from the back of the list.
8101cb0ef41Sopenharmony_ci  int i = len - kSlotsPerEntry;
8111cb0ef41Sopenharmony_ci  while (i >= 0) {
8121cb0ef41Sopenharmony_ci    MaybeObject obj = Get(i + kCodeSlotOffset);
8131cb0ef41Sopenharmony_ci    if (obj->IsCleared()) {
8141cb0ef41Sopenharmony_ci      len = FillEntryFromBack(i, len);
8151cb0ef41Sopenharmony_ci      i -= kSlotsPerEntry;
8161cb0ef41Sopenharmony_ci      continue;
8171cb0ef41Sopenharmony_ci    }
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ci    if (fn(CodeT::cast(obj->GetHeapObjectAssumeWeak()),
8201cb0ef41Sopenharmony_ci           static_cast<DependencyGroups>(
8211cb0ef41Sopenharmony_ci               Get(i + kGroupsSlotOffset).ToSmi().value()))) {
8221cb0ef41Sopenharmony_ci      len = FillEntryFromBack(i, len);
8231cb0ef41Sopenharmony_ci    }
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci    i -= kSlotsPerEntry;
8261cb0ef41Sopenharmony_ci  }
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci  set_length(len);
8291cb0ef41Sopenharmony_ci}
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_cibool DependentCode::MarkCodeForDeoptimization(
8321cb0ef41Sopenharmony_ci    DependentCode::DependencyGroups deopt_groups) {
8331cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ci  bool marked_something = false;
8361cb0ef41Sopenharmony_ci  IterateAndCompact([&](CodeT codet, DependencyGroups groups) {
8371cb0ef41Sopenharmony_ci    if ((groups & deopt_groups) == 0) return false;
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ci    // TODO(v8:11880): avoid roundtrips between cdc and code.
8401cb0ef41Sopenharmony_ci    Code code = FromCodeT(codet);
8411cb0ef41Sopenharmony_ci    if (!code.marked_for_deoptimization()) {
8421cb0ef41Sopenharmony_ci      code.SetMarkedForDeoptimization("code dependencies");
8431cb0ef41Sopenharmony_ci      marked_something = true;
8441cb0ef41Sopenharmony_ci    }
8451cb0ef41Sopenharmony_ci
8461cb0ef41Sopenharmony_ci    return true;
8471cb0ef41Sopenharmony_ci  });
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ci  return marked_something;
8501cb0ef41Sopenharmony_ci}
8511cb0ef41Sopenharmony_ci
8521cb0ef41Sopenharmony_ciint DependentCode::FillEntryFromBack(int index, int length) {
8531cb0ef41Sopenharmony_ci  DCHECK_EQ(index % 2, 0);
8541cb0ef41Sopenharmony_ci  DCHECK_EQ(length % 2, 0);
8551cb0ef41Sopenharmony_ci  for (int i = length - kSlotsPerEntry; i > index; i -= kSlotsPerEntry) {
8561cb0ef41Sopenharmony_ci    MaybeObject obj = Get(i + kCodeSlotOffset);
8571cb0ef41Sopenharmony_ci    if (obj->IsCleared()) continue;
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci    Set(index + kCodeSlotOffset, obj);
8601cb0ef41Sopenharmony_ci    Set(index + kGroupsSlotOffset, Get(i + kGroupsSlotOffset),
8611cb0ef41Sopenharmony_ci        SKIP_WRITE_BARRIER);
8621cb0ef41Sopenharmony_ci    return i;
8631cb0ef41Sopenharmony_ci  }
8641cb0ef41Sopenharmony_ci  return index;  // No non-cleared entry found.
8651cb0ef41Sopenharmony_ci}
8661cb0ef41Sopenharmony_ci
8671cb0ef41Sopenharmony_civoid DependentCode::DeoptimizeDependentCodeGroup(
8681cb0ef41Sopenharmony_ci    Isolate* isolate, DependentCode::DependencyGroups groups) {
8691cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc_scope;
8701cb0ef41Sopenharmony_ci  bool marked_something = MarkCodeForDeoptimization(groups);
8711cb0ef41Sopenharmony_ci  if (marked_something) {
8721cb0ef41Sopenharmony_ci    DCHECK(AllowCodeDependencyChange::IsAllowed());
8731cb0ef41Sopenharmony_ci    Deoptimizer::DeoptimizeMarkedCode(isolate);
8741cb0ef41Sopenharmony_ci  }
8751cb0ef41Sopenharmony_ci}
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci// static
8781cb0ef41Sopenharmony_ciDependentCode DependentCode::empty_dependent_code(const ReadOnlyRoots& roots) {
8791cb0ef41Sopenharmony_ci  return DependentCode::cast(roots.empty_weak_array_list());
8801cb0ef41Sopenharmony_ci}
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_civoid Code::SetMarkedForDeoptimization(const char* reason) {
8831cb0ef41Sopenharmony_ci  set_marked_for_deoptimization(true);
8841cb0ef41Sopenharmony_ci  Deoptimizer::TraceMarkForDeoptimization(*this, reason);
8851cb0ef41Sopenharmony_ci}
8861cb0ef41Sopenharmony_ci
8871cb0ef41Sopenharmony_ciconst char* DependentCode::DependencyGroupName(DependencyGroup group) {
8881cb0ef41Sopenharmony_ci  switch (group) {
8891cb0ef41Sopenharmony_ci    case kTransitionGroup:
8901cb0ef41Sopenharmony_ci      return "transition";
8911cb0ef41Sopenharmony_ci    case kPrototypeCheckGroup:
8921cb0ef41Sopenharmony_ci      return "prototype-check";
8931cb0ef41Sopenharmony_ci    case kPropertyCellChangedGroup:
8941cb0ef41Sopenharmony_ci      return "property-cell-changed";
8951cb0ef41Sopenharmony_ci    case kFieldConstGroup:
8961cb0ef41Sopenharmony_ci      return "field-const";
8971cb0ef41Sopenharmony_ci    case kFieldTypeGroup:
8981cb0ef41Sopenharmony_ci      return "field-type";
8991cb0ef41Sopenharmony_ci    case kFieldRepresentationGroup:
9001cb0ef41Sopenharmony_ci      return "field-representation";
9011cb0ef41Sopenharmony_ci    case kInitialMapChangedGroup:
9021cb0ef41Sopenharmony_ci      return "initial-map-changed";
9031cb0ef41Sopenharmony_ci    case kAllocationSiteTenuringChangedGroup:
9041cb0ef41Sopenharmony_ci      return "allocation-site-tenuring-changed";
9051cb0ef41Sopenharmony_ci    case kAllocationSiteTransitionChangedGroup:
9061cb0ef41Sopenharmony_ci      return "allocation-site-transition-changed";
9071cb0ef41Sopenharmony_ci  }
9081cb0ef41Sopenharmony_ci  UNREACHABLE();
9091cb0ef41Sopenharmony_ci}
9101cb0ef41Sopenharmony_ci
9111cb0ef41Sopenharmony_ci}  // namespace internal
9121cb0ef41Sopenharmony_ci}  // namespace v8
913