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