11cb0ef41Sopenharmony_ci// Copyright 2017 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#ifndef V8_OBJECTS_CODE_INL_H_ 61cb0ef41Sopenharmony_ci#define V8_OBJECTS_CODE_INL_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/memory.h" 91cb0ef41Sopenharmony_ci#include "src/baseline/bytecode-offset-iterator.h" 101cb0ef41Sopenharmony_ci#include "src/codegen/code-desc.h" 111cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h" 121cb0ef41Sopenharmony_ci#include "src/common/globals.h" 131cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 141cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h" 151cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-register.h" 161cb0ef41Sopenharmony_ci#include "src/objects/code.h" 171cb0ef41Sopenharmony_ci#include "src/objects/dictionary.h" 181cb0ef41Sopenharmony_ci#include "src/objects/instance-type-inl.h" 191cb0ef41Sopenharmony_ci#include "src/objects/map-inl.h" 201cb0ef41Sopenharmony_ci#include "src/objects/maybe-object-inl.h" 211cb0ef41Sopenharmony_ci#include "src/objects/oddball.h" 221cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info-inl.h" 231cb0ef41Sopenharmony_ci#include "src/objects/smi-inl.h" 241cb0ef41Sopenharmony_ci#include "src/utils/utils.h" 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci// Has to be the last include (doesn't have include guards): 271cb0ef41Sopenharmony_ci#include "src/objects/object-macros.h" 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cinamespace v8 { 301cb0ef41Sopenharmony_cinamespace internal { 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include "torque-generated/src/objects/code-tq-inl.inc" 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciOBJECT_CONSTRUCTORS_IMPL(DeoptimizationData, FixedArray) 351cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(BytecodeArray) 361cb0ef41Sopenharmony_ciOBJECT_CONSTRUCTORS_IMPL(AbstractCode, HeapObject) 371cb0ef41Sopenharmony_ciOBJECT_CONSTRUCTORS_IMPL(DependentCode, WeakArrayList) 381cb0ef41Sopenharmony_ciOBJECT_CONSTRUCTORS_IMPL(CodeDataContainer, HeapObject) 391cb0ef41Sopenharmony_ciNEVER_READ_ONLY_SPACE_IMPL(CodeDataContainer) 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ciNEVER_READ_ONLY_SPACE_IMPL(AbstractCode) 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciCAST_ACCESSOR(AbstractCode) 441cb0ef41Sopenharmony_ciCAST_ACCESSOR(Code) 451cb0ef41Sopenharmony_ciCAST_ACCESSOR(CodeDataContainer) 461cb0ef41Sopenharmony_ciCAST_ACCESSOR(DependentCode) 471cb0ef41Sopenharmony_ciCAST_ACCESSOR(DeoptimizationData) 481cb0ef41Sopenharmony_ciCAST_ACCESSOR(DeoptimizationLiteralArray) 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciint AbstractCode::raw_instruction_size() { 511cb0ef41Sopenharmony_ci if (IsCode()) { 521cb0ef41Sopenharmony_ci return GetCode().raw_instruction_size(); 531cb0ef41Sopenharmony_ci } else { 541cb0ef41Sopenharmony_ci return GetBytecodeArray().length(); 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci} 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ciint AbstractCode::InstructionSize() { 591cb0ef41Sopenharmony_ci if (IsCode()) { 601cb0ef41Sopenharmony_ci return GetCode().InstructionSize(); 611cb0ef41Sopenharmony_ci } else { 621cb0ef41Sopenharmony_ci return GetBytecodeArray().length(); 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci} 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ciByteArray AbstractCode::SourcePositionTableInternal() { 671cb0ef41Sopenharmony_ci if (IsCode()) { 681cb0ef41Sopenharmony_ci DCHECK_NE(GetCode().kind(), CodeKind::BASELINE); 691cb0ef41Sopenharmony_ci return GetCode().source_position_table(); 701cb0ef41Sopenharmony_ci } else { 711cb0ef41Sopenharmony_ci return GetBytecodeArray().SourcePositionTable(); 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ciByteArray AbstractCode::SourcePositionTable(SharedFunctionInfo sfi) { 761cb0ef41Sopenharmony_ci if (IsCode()) { 771cb0ef41Sopenharmony_ci return GetCode().SourcePositionTable(sfi); 781cb0ef41Sopenharmony_ci } else { 791cb0ef41Sopenharmony_ci return GetBytecodeArray().SourcePositionTable(); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci} 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ciint AbstractCode::SizeIncludingMetadata() { 841cb0ef41Sopenharmony_ci if (IsCode()) { 851cb0ef41Sopenharmony_ci return GetCode().SizeIncludingMetadata(); 861cb0ef41Sopenharmony_ci } else { 871cb0ef41Sopenharmony_ci return GetBytecodeArray().SizeIncludingMetadata(); 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ciAddress AbstractCode::raw_instruction_start() { 921cb0ef41Sopenharmony_ci if (IsCode()) { 931cb0ef41Sopenharmony_ci return GetCode().raw_instruction_start(); 941cb0ef41Sopenharmony_ci } else { 951cb0ef41Sopenharmony_ci return GetBytecodeArray().GetFirstBytecodeAddress(); 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci} 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciAddress AbstractCode::InstructionStart() { 1001cb0ef41Sopenharmony_ci if (IsCode()) { 1011cb0ef41Sopenharmony_ci return GetCode().InstructionStart(); 1021cb0ef41Sopenharmony_ci } else { 1031cb0ef41Sopenharmony_ci return GetBytecodeArray().GetFirstBytecodeAddress(); 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ciAddress AbstractCode::raw_instruction_end() { 1081cb0ef41Sopenharmony_ci if (IsCode()) { 1091cb0ef41Sopenharmony_ci return GetCode().raw_instruction_end(); 1101cb0ef41Sopenharmony_ci } else { 1111cb0ef41Sopenharmony_ci return GetBytecodeArray().GetFirstBytecodeAddress() + 1121cb0ef41Sopenharmony_ci GetBytecodeArray().length(); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci} 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ciAddress AbstractCode::InstructionEnd() { 1171cb0ef41Sopenharmony_ci if (IsCode()) { 1181cb0ef41Sopenharmony_ci return GetCode().InstructionEnd(); 1191cb0ef41Sopenharmony_ci } else { 1201cb0ef41Sopenharmony_ci return GetBytecodeArray().GetFirstBytecodeAddress() + 1211cb0ef41Sopenharmony_ci GetBytecodeArray().length(); 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci} 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_cibool AbstractCode::contains(Isolate* isolate, Address inner_pointer) { 1261cb0ef41Sopenharmony_ci PtrComprCageBase cage_base(isolate); 1271cb0ef41Sopenharmony_ci if (IsCode(cage_base)) { 1281cb0ef41Sopenharmony_ci return GetCode().contains(isolate, inner_pointer); 1291cb0ef41Sopenharmony_ci } else { 1301cb0ef41Sopenharmony_ci return (address() <= inner_pointer) && 1311cb0ef41Sopenharmony_ci (inner_pointer <= address() + Size(cage_base)); 1321cb0ef41Sopenharmony_ci } 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ciCodeKind AbstractCode::kind() { 1361cb0ef41Sopenharmony_ci return IsCode() ? GetCode().kind() : CodeKind::INTERPRETED_FUNCTION; 1371cb0ef41Sopenharmony_ci} 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ciCode AbstractCode::GetCode() { return Code::cast(*this); } 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ciBytecodeArray AbstractCode::GetBytecodeArray() { 1421cb0ef41Sopenharmony_ci return BytecodeArray::cast(*this); 1431cb0ef41Sopenharmony_ci} 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ciOBJECT_CONSTRUCTORS_IMPL(Code, HeapObject) 1461cb0ef41Sopenharmony_ciNEVER_READ_ONLY_SPACE_IMPL(Code) 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ciINT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset) 1491cb0ef41Sopenharmony_ciINT_ACCESSORS(Code, raw_metadata_size, kMetadataSizeOffset) 1501cb0ef41Sopenharmony_ciINT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset) 1511cb0ef41Sopenharmony_ciINT_ACCESSORS(Code, code_comments_offset, kCodeCommentsOffsetOffset) 1521cb0ef41Sopenharmony_ciINT32_ACCESSORS(Code, unwinding_info_offset, kUnwindingInfoOffsetOffset) 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci// Same as ACCESSORS_CHECKED2 macro but with Code as a host and using 1551cb0ef41Sopenharmony_ci// main_cage_base() for computing the base. 1561cb0ef41Sopenharmony_ci#define CODE_ACCESSORS_CHECKED2(name, type, offset, get_condition, \ 1571cb0ef41Sopenharmony_ci set_condition) \ 1581cb0ef41Sopenharmony_ci type Code::name() const { \ 1591cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = main_cage_base(); \ 1601cb0ef41Sopenharmony_ci return Code::name(cage_base); \ 1611cb0ef41Sopenharmony_ci } \ 1621cb0ef41Sopenharmony_ci type Code::name(PtrComprCageBase cage_base) const { \ 1631cb0ef41Sopenharmony_ci type value = TaggedField<type, offset>::load(cage_base, *this); \ 1641cb0ef41Sopenharmony_ci DCHECK(get_condition); \ 1651cb0ef41Sopenharmony_ci return value; \ 1661cb0ef41Sopenharmony_ci } \ 1671cb0ef41Sopenharmony_ci void Code::set_##name(type value, WriteBarrierMode mode) { \ 1681cb0ef41Sopenharmony_ci DCHECK(set_condition); \ 1691cb0ef41Sopenharmony_ci TaggedField<type, offset>::store(*this, value); \ 1701cb0ef41Sopenharmony_ci CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); \ 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci// Same as RELEASE_ACQUIRE_ACCESSORS_CHECKED2 macro but with Code as a host and 1741cb0ef41Sopenharmony_ci// using main_cage_base(kRelaxedLoad) for computing the base. 1751cb0ef41Sopenharmony_ci#define RELEASE_ACQUIRE_CODE_ACCESSORS_CHECKED2(name, type, offset, \ 1761cb0ef41Sopenharmony_ci get_condition, set_condition) \ 1771cb0ef41Sopenharmony_ci type Code::name(AcquireLoadTag tag) const { \ 1781cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = main_cage_base(kRelaxedLoad); \ 1791cb0ef41Sopenharmony_ci return Code::name(cage_base, tag); \ 1801cb0ef41Sopenharmony_ci } \ 1811cb0ef41Sopenharmony_ci type Code::name(PtrComprCageBase cage_base, AcquireLoadTag) const { \ 1821cb0ef41Sopenharmony_ci type value = TaggedField<type, offset>::Acquire_Load(cage_base, *this); \ 1831cb0ef41Sopenharmony_ci DCHECK(get_condition); \ 1841cb0ef41Sopenharmony_ci return value; \ 1851cb0ef41Sopenharmony_ci } \ 1861cb0ef41Sopenharmony_ci void Code::set_##name(type value, ReleaseStoreTag, WriteBarrierMode mode) { \ 1871cb0ef41Sopenharmony_ci DCHECK(set_condition); \ 1881cb0ef41Sopenharmony_ci TaggedField<type, offset>::Release_Store(*this, value); \ 1891cb0ef41Sopenharmony_ci CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); \ 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci#define CODE_ACCESSORS(name, type, offset) \ 1931cb0ef41Sopenharmony_ci CODE_ACCESSORS_CHECKED2(name, type, offset, true, true) 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci#define RELEASE_ACQUIRE_CODE_ACCESSORS(name, type, offset) \ 1961cb0ef41Sopenharmony_ci RELEASE_ACQUIRE_CODE_ACCESSORS_CHECKED2(name, type, offset, \ 1971cb0ef41Sopenharmony_ci !ObjectInYoungGeneration(value), \ 1981cb0ef41Sopenharmony_ci !ObjectInYoungGeneration(value)) 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ciCODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset) 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ciCODE_ACCESSORS_CHECKED2(deoptimization_data, FixedArray, 2031cb0ef41Sopenharmony_ci kDeoptimizationDataOrInterpreterDataOffset, 2041cb0ef41Sopenharmony_ci kind() != CodeKind::BASELINE, 2051cb0ef41Sopenharmony_ci kind() != CodeKind::BASELINE && 2061cb0ef41Sopenharmony_ci !ObjectInYoungGeneration(value)) 2071cb0ef41Sopenharmony_ciCODE_ACCESSORS_CHECKED2(bytecode_or_interpreter_data, HeapObject, 2081cb0ef41Sopenharmony_ci kDeoptimizationDataOrInterpreterDataOffset, 2091cb0ef41Sopenharmony_ci kind() == CodeKind::BASELINE, 2101cb0ef41Sopenharmony_ci kind() == CodeKind::BASELINE && 2111cb0ef41Sopenharmony_ci !ObjectInYoungGeneration(value)) 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ciCODE_ACCESSORS_CHECKED2(source_position_table, ByteArray, kPositionTableOffset, 2141cb0ef41Sopenharmony_ci kind() != CodeKind::BASELINE, 2151cb0ef41Sopenharmony_ci kind() != CodeKind::BASELINE && 2161cb0ef41Sopenharmony_ci !ObjectInYoungGeneration(value)) 2171cb0ef41Sopenharmony_ciCODE_ACCESSORS_CHECKED2(bytecode_offset_table, ByteArray, kPositionTableOffset, 2181cb0ef41Sopenharmony_ci kind() == CodeKind::BASELINE, 2191cb0ef41Sopenharmony_ci kind() == CodeKind::BASELINE && 2201cb0ef41Sopenharmony_ci !ObjectInYoungGeneration(value)) 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci// Concurrent marker needs to access kind specific flags in code data container. 2231cb0ef41Sopenharmony_ciRELEASE_ACQUIRE_CODE_ACCESSORS(code_data_container, CodeDataContainer, 2241cb0ef41Sopenharmony_ci kCodeDataContainerOffset) 2251cb0ef41Sopenharmony_ci#undef CODE_ACCESSORS 2261cb0ef41Sopenharmony_ci#undef CODE_ACCESSORS_CHECKED2 2271cb0ef41Sopenharmony_ci#undef RELEASE_ACQUIRE_CODE_ACCESSORS 2281cb0ef41Sopenharmony_ci#undef RELEASE_ACQUIRE_CODE_ACCESSORS_CHECKED2 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ciPtrComprCageBase Code::main_cage_base() const { 2311cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 2321cb0ef41Sopenharmony_ci Address cage_base_hi = ReadField<Tagged_t>(kMainCageBaseUpper32BitsOffset); 2331cb0ef41Sopenharmony_ci return PtrComprCageBase(cage_base_hi << 32); 2341cb0ef41Sopenharmony_ci#else 2351cb0ef41Sopenharmony_ci return GetPtrComprCageBase(*this); 2361cb0ef41Sopenharmony_ci#endif 2371cb0ef41Sopenharmony_ci} 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ciPtrComprCageBase Code::main_cage_base(RelaxedLoadTag) const { 2401cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 2411cb0ef41Sopenharmony_ci Address cage_base_hi = 2421cb0ef41Sopenharmony_ci Relaxed_ReadField<Tagged_t>(kMainCageBaseUpper32BitsOffset); 2431cb0ef41Sopenharmony_ci return PtrComprCageBase(cage_base_hi << 32); 2441cb0ef41Sopenharmony_ci#else 2451cb0ef41Sopenharmony_ci return GetPtrComprCageBase(*this); 2461cb0ef41Sopenharmony_ci#endif 2471cb0ef41Sopenharmony_ci} 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_civoid Code::set_main_cage_base(Address cage_base, RelaxedStoreTag) { 2501cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 2511cb0ef41Sopenharmony_ci Tagged_t cage_base_hi = static_cast<Tagged_t>(cage_base >> 32); 2521cb0ef41Sopenharmony_ci Relaxed_WriteField<Tagged_t>(kMainCageBaseUpper32BitsOffset, cage_base_hi); 2531cb0ef41Sopenharmony_ci#else 2541cb0ef41Sopenharmony_ci UNREACHABLE(); 2551cb0ef41Sopenharmony_ci#endif 2561cb0ef41Sopenharmony_ci} 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ciCodeDataContainer Code::GCSafeCodeDataContainer(AcquireLoadTag) const { 2591cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = main_cage_base(kRelaxedLoad); 2601cb0ef41Sopenharmony_ci HeapObject object = 2611cb0ef41Sopenharmony_ci TaggedField<HeapObject, kCodeDataContainerOffset>::Acquire_Load(cage_base, 2621cb0ef41Sopenharmony_ci *this); 2631cb0ef41Sopenharmony_ci DCHECK(!ObjectInYoungGeneration(object)); 2641cb0ef41Sopenharmony_ci CodeDataContainer code_data_container = 2651cb0ef41Sopenharmony_ci ForwardingAddress(CodeDataContainer::unchecked_cast(object)); 2661cb0ef41Sopenharmony_ci return code_data_container; 2671cb0ef41Sopenharmony_ci} 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_ci// Helper functions for converting Code objects to CodeDataContainer and back 2701cb0ef41Sopenharmony_ci// when V8_EXTERNAL_CODE_SPACE is enabled. 2711cb0ef41Sopenharmony_ciinline CodeT ToCodeT(Code code) { 2721cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 2731cb0ef41Sopenharmony_ci return code.code_data_container(kAcquireLoad); 2741cb0ef41Sopenharmony_ci#else 2751cb0ef41Sopenharmony_ci return code; 2761cb0ef41Sopenharmony_ci#endif 2771cb0ef41Sopenharmony_ci} 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ciinline Handle<CodeT> ToCodeT(Handle<Code> code, Isolate* isolate) { 2801cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 2811cb0ef41Sopenharmony_ci return handle(ToCodeT(*code), isolate); 2821cb0ef41Sopenharmony_ci#else 2831cb0ef41Sopenharmony_ci return code; 2841cb0ef41Sopenharmony_ci#endif 2851cb0ef41Sopenharmony_ci} 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ciinline MaybeHandle<CodeT> ToCodeT(MaybeHandle<Code> maybe_code, 2881cb0ef41Sopenharmony_ci Isolate* isolate) { 2891cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 2901cb0ef41Sopenharmony_ci Handle<Code> code; 2911cb0ef41Sopenharmony_ci if (maybe_code.ToHandle(&code)) return ToCodeT(code, isolate); 2921cb0ef41Sopenharmony_ci return {}; 2931cb0ef41Sopenharmony_ci#else 2941cb0ef41Sopenharmony_ci return maybe_code; 2951cb0ef41Sopenharmony_ci#endif 2961cb0ef41Sopenharmony_ci} 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ciinline Code FromCodeT(CodeT code) { 2991cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 3001cb0ef41Sopenharmony_ci return code.code(); 3011cb0ef41Sopenharmony_ci#else 3021cb0ef41Sopenharmony_ci return code; 3031cb0ef41Sopenharmony_ci#endif 3041cb0ef41Sopenharmony_ci} 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ciinline Code FromCodeT(CodeT code, RelaxedLoadTag) { 3071cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 3081cb0ef41Sopenharmony_ci return code.code(kRelaxedLoad); 3091cb0ef41Sopenharmony_ci#else 3101cb0ef41Sopenharmony_ci return code; 3111cb0ef41Sopenharmony_ci#endif 3121cb0ef41Sopenharmony_ci} 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ciinline Handle<Code> FromCodeT(Handle<CodeT> code, Isolate* isolate) { 3151cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 3161cb0ef41Sopenharmony_ci return handle(FromCodeT(*code), isolate); 3171cb0ef41Sopenharmony_ci#else 3181cb0ef41Sopenharmony_ci return code; 3191cb0ef41Sopenharmony_ci#endif 3201cb0ef41Sopenharmony_ci} 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ciinline Handle<AbstractCode> ToAbstractCode(Handle<CodeT> code, 3231cb0ef41Sopenharmony_ci Isolate* isolate) { 3241cb0ef41Sopenharmony_ci return Handle<AbstractCode>::cast(FromCodeT(code, isolate)); 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ciinline CodeDataContainer CodeDataContainerFromCodeT(CodeT code) { 3281cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 3291cb0ef41Sopenharmony_ci return code; 3301cb0ef41Sopenharmony_ci#else 3311cb0ef41Sopenharmony_ci return code.code_data_container(kAcquireLoad); 3321cb0ef41Sopenharmony_ci#endif 3331cb0ef41Sopenharmony_ci} 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_civoid Code::WipeOutHeader() { 3361cb0ef41Sopenharmony_ci WRITE_FIELD(*this, kRelocationInfoOffset, Smi::FromInt(0)); 3371cb0ef41Sopenharmony_ci WRITE_FIELD(*this, kDeoptimizationDataOrInterpreterDataOffset, 3381cb0ef41Sopenharmony_ci Smi::FromInt(0)); 3391cb0ef41Sopenharmony_ci WRITE_FIELD(*this, kPositionTableOffset, Smi::FromInt(0)); 3401cb0ef41Sopenharmony_ci WRITE_FIELD(*this, kCodeDataContainerOffset, Smi::FromInt(0)); 3411cb0ef41Sopenharmony_ci if (V8_EXTERNAL_CODE_SPACE_BOOL) { 3421cb0ef41Sopenharmony_ci set_main_cage_base(kNullAddress, kRelaxedStore); 3431cb0ef41Sopenharmony_ci } 3441cb0ef41Sopenharmony_ci} 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_civoid Code::clear_padding() { 3471cb0ef41Sopenharmony_ci // Clear the padding between the header and `raw_body_start`. 3481cb0ef41Sopenharmony_ci if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { 3491cb0ef41Sopenharmony_ci memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0, 3501cb0ef41Sopenharmony_ci FIELD_SIZE(kOptionalPaddingOffset)); 3511cb0ef41Sopenharmony_ci } 3521cb0ef41Sopenharmony_ci 3531cb0ef41Sopenharmony_ci // Clear the padding after `raw_body_end`. 3541cb0ef41Sopenharmony_ci size_t trailing_padding_size = 3551cb0ef41Sopenharmony_ci CodeSize() - Code::kHeaderSize - raw_body_size(); 3561cb0ef41Sopenharmony_ci memset(reinterpret_cast<void*>(raw_body_end()), 0, trailing_padding_size); 3571cb0ef41Sopenharmony_ci} 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ciByteArray Code::SourcePositionTable(SharedFunctionInfo sfi) const { 3601cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 3611cb0ef41Sopenharmony_ci if (kind() == CodeKind::BASELINE) { 3621cb0ef41Sopenharmony_ci return sfi.GetBytecodeArray(sfi.GetIsolate()).SourcePositionTable(); 3631cb0ef41Sopenharmony_ci } 3641cb0ef41Sopenharmony_ci return source_position_table(); 3651cb0ef41Sopenharmony_ci} 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ciObject Code::next_code_link() const { 3681cb0ef41Sopenharmony_ci return code_data_container(kAcquireLoad).next_code_link(); 3691cb0ef41Sopenharmony_ci} 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_civoid Code::set_next_code_link(Object value) { 3721cb0ef41Sopenharmony_ci code_data_container(kAcquireLoad).set_next_code_link(value); 3731cb0ef41Sopenharmony_ci} 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ciAddress Code::raw_body_start() const { return raw_instruction_start(); } 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_ciAddress Code::raw_body_end() const { 3781cb0ef41Sopenharmony_ci return raw_body_start() + raw_body_size(); 3791cb0ef41Sopenharmony_ci} 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ciint Code::raw_body_size() const { 3821cb0ef41Sopenharmony_ci return raw_instruction_size() + raw_metadata_size(); 3831cb0ef41Sopenharmony_ci} 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ciint Code::InstructionSize() const { 3861cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 3871cb0ef41Sopenharmony_ci ? OffHeapInstructionSize(*this, builtin_id()) 3881cb0ef41Sopenharmony_ci : raw_instruction_size(); 3891cb0ef41Sopenharmony_ci} 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ciAddress Code::raw_instruction_start() const { 3921cb0ef41Sopenharmony_ci return field_address(kHeaderSize); 3931cb0ef41Sopenharmony_ci} 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ciAddress Code::InstructionStart() const { 3961cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 3971cb0ef41Sopenharmony_ci ? i::OffHeapInstructionStart(*this, builtin_id()) 3981cb0ef41Sopenharmony_ci : raw_instruction_start(); 3991cb0ef41Sopenharmony_ci} 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ciAddress Code::raw_instruction_end() const { 4021cb0ef41Sopenharmony_ci return raw_instruction_start() + raw_instruction_size(); 4031cb0ef41Sopenharmony_ci} 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ciAddress Code::InstructionEnd() const { 4061cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 4071cb0ef41Sopenharmony_ci ? i::OffHeapInstructionEnd(*this, builtin_id()) 4081cb0ef41Sopenharmony_ci : raw_instruction_end(); 4091cb0ef41Sopenharmony_ci} 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ciAddress Code::raw_metadata_start() const { 4121cb0ef41Sopenharmony_ci return raw_instruction_start() + raw_instruction_size(); 4131cb0ef41Sopenharmony_ci} 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ciAddress Code::InstructionStart(Isolate* isolate, Address pc) const { 4161cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 4171cb0ef41Sopenharmony_ci ? OffHeapInstructionStart(isolate, pc) 4181cb0ef41Sopenharmony_ci : raw_instruction_start(); 4191cb0ef41Sopenharmony_ci} 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ciAddress Code::InstructionEnd(Isolate* isolate, Address pc) const { 4221cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 4231cb0ef41Sopenharmony_ci ? OffHeapInstructionEnd(isolate, pc) 4241cb0ef41Sopenharmony_ci : raw_instruction_end(); 4251cb0ef41Sopenharmony_ci} 4261cb0ef41Sopenharmony_ci 4271cb0ef41Sopenharmony_ciint Code::GetOffsetFromInstructionStart(Isolate* isolate, Address pc) const { 4281cb0ef41Sopenharmony_ci Address instruction_start = InstructionStart(isolate, pc); 4291cb0ef41Sopenharmony_ci Address offset = pc - instruction_start; 4301cb0ef41Sopenharmony_ci DCHECK_LE(offset, InstructionSize()); 4311cb0ef41Sopenharmony_ci return static_cast<int>(offset); 4321cb0ef41Sopenharmony_ci} 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ciAddress Code::raw_metadata_end() const { 4351cb0ef41Sopenharmony_ci return raw_metadata_start() + raw_metadata_size(); 4361cb0ef41Sopenharmony_ci} 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ciint Code::MetadataSize() const { 4391cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 4401cb0ef41Sopenharmony_ci ? OffHeapMetadataSize(*this, builtin_id()) 4411cb0ef41Sopenharmony_ci : raw_metadata_size(); 4421cb0ef41Sopenharmony_ci} 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ciint Code::SizeIncludingMetadata() const { 4451cb0ef41Sopenharmony_ci int size = CodeSize(); 4461cb0ef41Sopenharmony_ci size += relocation_info().Size(); 4471cb0ef41Sopenharmony_ci if (kind() != CodeKind::BASELINE) { 4481cb0ef41Sopenharmony_ci size += deoptimization_data().Size(); 4491cb0ef41Sopenharmony_ci } 4501cb0ef41Sopenharmony_ci return size; 4511cb0ef41Sopenharmony_ci} 4521cb0ef41Sopenharmony_ci 4531cb0ef41Sopenharmony_ciAddress Code::SafepointTableAddress() const { 4541cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 4551cb0ef41Sopenharmony_ci ? OffHeapSafepointTableAddress(*this, builtin_id()) 4561cb0ef41Sopenharmony_ci : raw_metadata_start() + safepoint_table_offset(); 4571cb0ef41Sopenharmony_ci} 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ciint Code::safepoint_table_size() const { 4601cb0ef41Sopenharmony_ci DCHECK_GE(handler_table_offset() - safepoint_table_offset(), 0); 4611cb0ef41Sopenharmony_ci return handler_table_offset() - safepoint_table_offset(); 4621cb0ef41Sopenharmony_ci} 4631cb0ef41Sopenharmony_ci 4641cb0ef41Sopenharmony_cibool Code::has_safepoint_table() const { return safepoint_table_size() > 0; } 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ciAddress Code::HandlerTableAddress() const { 4671cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 4681cb0ef41Sopenharmony_ci ? OffHeapHandlerTableAddress(*this, builtin_id()) 4691cb0ef41Sopenharmony_ci : raw_metadata_start() + handler_table_offset(); 4701cb0ef41Sopenharmony_ci} 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ciint Code::handler_table_size() const { 4731cb0ef41Sopenharmony_ci DCHECK_GE(constant_pool_offset() - handler_table_offset(), 0); 4741cb0ef41Sopenharmony_ci return constant_pool_offset() - handler_table_offset(); 4751cb0ef41Sopenharmony_ci} 4761cb0ef41Sopenharmony_ci 4771cb0ef41Sopenharmony_cibool Code::has_handler_table() const { return handler_table_size() > 0; } 4781cb0ef41Sopenharmony_ci 4791cb0ef41Sopenharmony_ciint Code::constant_pool_size() const { 4801cb0ef41Sopenharmony_ci const int size = code_comments_offset() - constant_pool_offset(); 4811cb0ef41Sopenharmony_ci DCHECK_IMPLIES(!FLAG_enable_embedded_constant_pool, size == 0); 4821cb0ef41Sopenharmony_ci DCHECK_GE(size, 0); 4831cb0ef41Sopenharmony_ci return size; 4841cb0ef41Sopenharmony_ci} 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_cibool Code::has_constant_pool() const { return constant_pool_size() > 0; } 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ciint Code::code_comments_size() const { 4891cb0ef41Sopenharmony_ci DCHECK_GE(unwinding_info_offset() - code_comments_offset(), 0); 4901cb0ef41Sopenharmony_ci return unwinding_info_offset() - code_comments_offset(); 4911cb0ef41Sopenharmony_ci} 4921cb0ef41Sopenharmony_ci 4931cb0ef41Sopenharmony_cibool Code::has_code_comments() const { return code_comments_size() > 0; } 4941cb0ef41Sopenharmony_ci 4951cb0ef41Sopenharmony_ciByteArray Code::unchecked_relocation_info() const { 4961cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = main_cage_base(); 4971cb0ef41Sopenharmony_ci return ByteArray::unchecked_cast( 4981cb0ef41Sopenharmony_ci TaggedField<HeapObject, kRelocationInfoOffset>::load(cage_base, *this)); 4991cb0ef41Sopenharmony_ci} 5001cb0ef41Sopenharmony_ci 5011cb0ef41Sopenharmony_cibyte* Code::relocation_start() const { 5021cb0ef41Sopenharmony_ci return unchecked_relocation_info().GetDataStartAddress(); 5031cb0ef41Sopenharmony_ci} 5041cb0ef41Sopenharmony_ci 5051cb0ef41Sopenharmony_cibyte* Code::relocation_end() const { 5061cb0ef41Sopenharmony_ci return unchecked_relocation_info().GetDataEndAddress(); 5071cb0ef41Sopenharmony_ci} 5081cb0ef41Sopenharmony_ci 5091cb0ef41Sopenharmony_ciint Code::relocation_size() const { 5101cb0ef41Sopenharmony_ci return unchecked_relocation_info().length(); 5111cb0ef41Sopenharmony_ci} 5121cb0ef41Sopenharmony_ci 5131cb0ef41Sopenharmony_ciAddress Code::entry() const { return raw_instruction_start(); } 5141cb0ef41Sopenharmony_ci 5151cb0ef41Sopenharmony_cibool Code::contains(Isolate* isolate, Address inner_pointer) { 5161cb0ef41Sopenharmony_ci if (is_off_heap_trampoline()) { 5171cb0ef41Sopenharmony_ci if (OffHeapInstructionStart(isolate, inner_pointer) <= inner_pointer && 5181cb0ef41Sopenharmony_ci inner_pointer < OffHeapInstructionEnd(isolate, inner_pointer)) { 5191cb0ef41Sopenharmony_ci return true; 5201cb0ef41Sopenharmony_ci } 5211cb0ef41Sopenharmony_ci } 5221cb0ef41Sopenharmony_ci return (address() <= inner_pointer) && 5231cb0ef41Sopenharmony_ci (inner_pointer < address() + CodeSize()); 5241cb0ef41Sopenharmony_ci} 5251cb0ef41Sopenharmony_ci 5261cb0ef41Sopenharmony_ci// static 5271cb0ef41Sopenharmony_civoid Code::CopyRelocInfoToByteArray(ByteArray dest, const CodeDesc& desc) { 5281cb0ef41Sopenharmony_ci DCHECK_EQ(dest.length(), desc.reloc_size); 5291cb0ef41Sopenharmony_ci CopyBytes(dest.GetDataStartAddress(), 5301cb0ef41Sopenharmony_ci desc.buffer + desc.buffer_size - desc.reloc_size, 5311cb0ef41Sopenharmony_ci static_cast<size_t>(desc.reloc_size)); 5321cb0ef41Sopenharmony_ci} 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ciint Code::CodeSize() const { return SizeFor(raw_body_size()); } 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_ciDEF_GETTER(Code, Size, int) { return CodeSize(); } 5371cb0ef41Sopenharmony_ci 5381cb0ef41Sopenharmony_ciCodeKind Code::kind() const { 5391cb0ef41Sopenharmony_ci STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size); 5401cb0ef41Sopenharmony_ci const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset); 5411cb0ef41Sopenharmony_ci return KindField::decode(flags); 5421cb0ef41Sopenharmony_ci} 5431cb0ef41Sopenharmony_ci 5441cb0ef41Sopenharmony_ciint Code::GetBytecodeOffsetForBaselinePC(Address baseline_pc, 5451cb0ef41Sopenharmony_ci BytecodeArray bytecodes) { 5461cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 5471cb0ef41Sopenharmony_ci CHECK(!is_baseline_trampoline_builtin()); 5481cb0ef41Sopenharmony_ci if (is_baseline_leave_frame_builtin()) return kFunctionExitBytecodeOffset; 5491cb0ef41Sopenharmony_ci CHECK_EQ(kind(), CodeKind::BASELINE); 5501cb0ef41Sopenharmony_ci baseline::BytecodeOffsetIterator offset_iterator( 5511cb0ef41Sopenharmony_ci ByteArray::cast(bytecode_offset_table()), bytecodes); 5521cb0ef41Sopenharmony_ci Address pc = baseline_pc - InstructionStart(); 5531cb0ef41Sopenharmony_ci offset_iterator.AdvanceToPCOffset(pc); 5541cb0ef41Sopenharmony_ci return offset_iterator.current_bytecode_offset(); 5551cb0ef41Sopenharmony_ci} 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ciuintptr_t Code::GetBaselinePCForBytecodeOffset(int bytecode_offset, 5581cb0ef41Sopenharmony_ci BytecodeToPCPosition position, 5591cb0ef41Sopenharmony_ci BytecodeArray bytecodes) { 5601cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 5611cb0ef41Sopenharmony_ci CHECK_EQ(kind(), CodeKind::BASELINE); 5621cb0ef41Sopenharmony_ci baseline::BytecodeOffsetIterator offset_iterator( 5631cb0ef41Sopenharmony_ci ByteArray::cast(bytecode_offset_table()), bytecodes); 5641cb0ef41Sopenharmony_ci offset_iterator.AdvanceToBytecodeOffset(bytecode_offset); 5651cb0ef41Sopenharmony_ci uintptr_t pc = 0; 5661cb0ef41Sopenharmony_ci if (position == kPcAtStartOfBytecode) { 5671cb0ef41Sopenharmony_ci pc = offset_iterator.current_pc_start_offset(); 5681cb0ef41Sopenharmony_ci } else { 5691cb0ef41Sopenharmony_ci DCHECK_EQ(position, kPcAtEndOfBytecode); 5701cb0ef41Sopenharmony_ci pc = offset_iterator.current_pc_end_offset(); 5711cb0ef41Sopenharmony_ci } 5721cb0ef41Sopenharmony_ci return pc; 5731cb0ef41Sopenharmony_ci} 5741cb0ef41Sopenharmony_ci 5751cb0ef41Sopenharmony_ciuintptr_t Code::GetBaselineStartPCForBytecodeOffset(int bytecode_offset, 5761cb0ef41Sopenharmony_ci BytecodeArray bytecodes) { 5771cb0ef41Sopenharmony_ci return GetBaselinePCForBytecodeOffset(bytecode_offset, kPcAtStartOfBytecode, 5781cb0ef41Sopenharmony_ci bytecodes); 5791cb0ef41Sopenharmony_ci} 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ciuintptr_t Code::GetBaselineEndPCForBytecodeOffset(int bytecode_offset, 5821cb0ef41Sopenharmony_ci BytecodeArray bytecodes) { 5831cb0ef41Sopenharmony_ci return GetBaselinePCForBytecodeOffset(bytecode_offset, kPcAtEndOfBytecode, 5841cb0ef41Sopenharmony_ci bytecodes); 5851cb0ef41Sopenharmony_ci} 5861cb0ef41Sopenharmony_ci 5871cb0ef41Sopenharmony_ciuintptr_t Code::GetBaselinePCForNextExecutedBytecode(int bytecode_offset, 5881cb0ef41Sopenharmony_ci BytecodeArray bytecodes) { 5891cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 5901cb0ef41Sopenharmony_ci CHECK_EQ(kind(), CodeKind::BASELINE); 5911cb0ef41Sopenharmony_ci baseline::BytecodeOffsetIterator offset_iterator( 5921cb0ef41Sopenharmony_ci ByteArray::cast(bytecode_offset_table()), bytecodes); 5931cb0ef41Sopenharmony_ci Handle<BytecodeArray> bytecodes_handle( 5941cb0ef41Sopenharmony_ci reinterpret_cast<Address*>(&bytecodes)); 5951cb0ef41Sopenharmony_ci interpreter::BytecodeArrayIterator bytecode_iterator(bytecodes_handle, 5961cb0ef41Sopenharmony_ci bytecode_offset); 5971cb0ef41Sopenharmony_ci interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode(); 5981cb0ef41Sopenharmony_ci if (bytecode == interpreter::Bytecode::kJumpLoop) { 5991cb0ef41Sopenharmony_ci return GetBaselineStartPCForBytecodeOffset( 6001cb0ef41Sopenharmony_ci bytecode_iterator.GetJumpTargetOffset(), bytecodes); 6011cb0ef41Sopenharmony_ci } else { 6021cb0ef41Sopenharmony_ci DCHECK(!interpreter::Bytecodes::IsJump(bytecode)); 6031cb0ef41Sopenharmony_ci return GetBaselineEndPCForBytecodeOffset(bytecode_offset, bytecodes); 6041cb0ef41Sopenharmony_ci } 6051cb0ef41Sopenharmony_ci} 6061cb0ef41Sopenharmony_ci 6071cb0ef41Sopenharmony_civoid Code::initialize_flags(CodeKind kind, bool is_turbofanned, int stack_slots, 6081cb0ef41Sopenharmony_ci bool is_off_heap_trampoline) { 6091cb0ef41Sopenharmony_ci CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax); 6101cb0ef41Sopenharmony_ci DCHECK(!CodeKindIsInterpretedJSFunction(kind)); 6111cb0ef41Sopenharmony_ci uint32_t flags = KindField::encode(kind) | 6121cb0ef41Sopenharmony_ci IsTurbofannedField::encode(is_turbofanned) | 6131cb0ef41Sopenharmony_ci StackSlotsField::encode(stack_slots) | 6141cb0ef41Sopenharmony_ci IsOffHeapTrampoline::encode(is_off_heap_trampoline); 6151cb0ef41Sopenharmony_ci STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size); 6161cb0ef41Sopenharmony_ci RELAXED_WRITE_UINT32_FIELD(*this, kFlagsOffset, flags); 6171cb0ef41Sopenharmony_ci DCHECK_IMPLIES(stack_slots != 0, uses_safepoint_table()); 6181cb0ef41Sopenharmony_ci DCHECK_IMPLIES(!uses_safepoint_table(), stack_slots == 0); 6191cb0ef41Sopenharmony_ci} 6201cb0ef41Sopenharmony_ci 6211cb0ef41Sopenharmony_ciinline bool Code::is_interpreter_trampoline_builtin() const { 6221cb0ef41Sopenharmony_ci return IsInterpreterTrampolineBuiltin(builtin_id()); 6231cb0ef41Sopenharmony_ci} 6241cb0ef41Sopenharmony_ci 6251cb0ef41Sopenharmony_ciinline bool Code::is_baseline_trampoline_builtin() const { 6261cb0ef41Sopenharmony_ci return IsBaselineTrampolineBuiltin(builtin_id()); 6271cb0ef41Sopenharmony_ci} 6281cb0ef41Sopenharmony_ci 6291cb0ef41Sopenharmony_ciinline bool Code::is_baseline_leave_frame_builtin() const { 6301cb0ef41Sopenharmony_ci return builtin_id() == Builtin::kBaselineLeaveFrame; 6311cb0ef41Sopenharmony_ci} 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 6341cb0ef41Sopenharmony_ci// Note, must be in sync with Code::checks_tiering_state(). 6351cb0ef41Sopenharmony_ciinline bool CodeDataContainer::checks_tiering_state() const { 6361cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 6371cb0ef41Sopenharmony_ci bool checks_state = (builtin_id() == Builtin::kCompileLazy || 6381cb0ef41Sopenharmony_ci builtin_id() == Builtin::kInterpreterEntryTrampoline || 6391cb0ef41Sopenharmony_ci CodeKindCanTierUp(kind())); 6401cb0ef41Sopenharmony_ci return checks_state || 6411cb0ef41Sopenharmony_ci (CodeKindCanDeoptimize(kind()) && marked_for_deoptimization()); 6421cb0ef41Sopenharmony_ci} 6431cb0ef41Sopenharmony_ci#endif // V8_EXTERNAL_CODE_SPACE 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci// Note, must be in sync with CodeDataContainer::checks_tiering_state(). 6461cb0ef41Sopenharmony_ciinline bool Code::checks_tiering_state() const { 6471cb0ef41Sopenharmony_ci bool checks_state = (builtin_id() == Builtin::kCompileLazy || 6481cb0ef41Sopenharmony_ci builtin_id() == Builtin::kInterpreterEntryTrampoline || 6491cb0ef41Sopenharmony_ci CodeKindCanTierUp(kind())); 6501cb0ef41Sopenharmony_ci return checks_state || 6511cb0ef41Sopenharmony_ci (CodeKindCanDeoptimize(kind()) && marked_for_deoptimization()); 6521cb0ef41Sopenharmony_ci} 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ciinline bool Code::has_tagged_outgoing_params() const { 6551cb0ef41Sopenharmony_ci return kind() != CodeKind::JS_TO_WASM_FUNCTION && 6561cb0ef41Sopenharmony_ci kind() != CodeKind::C_WASM_ENTRY && kind() != CodeKind::WASM_FUNCTION; 6571cb0ef41Sopenharmony_ci} 6581cb0ef41Sopenharmony_ci 6591cb0ef41Sopenharmony_ciinline bool Code::is_turbofanned() const { 6601cb0ef41Sopenharmony_ci const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset); 6611cb0ef41Sopenharmony_ci return IsTurbofannedField::decode(flags); 6621cb0ef41Sopenharmony_ci} 6631cb0ef41Sopenharmony_ci 6641cb0ef41Sopenharmony_cibool Code::is_maglevved() const { return kind() == CodeKind::MAGLEV; } 6651cb0ef41Sopenharmony_ci 6661cb0ef41Sopenharmony_ciinline bool Code::can_have_weak_objects() const { 6671cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(kind())); 6681cb0ef41Sopenharmony_ci int32_t flags = 6691cb0ef41Sopenharmony_ci code_data_container(kAcquireLoad).kind_specific_flags(kRelaxedLoad); 6701cb0ef41Sopenharmony_ci return CanHaveWeakObjectsField::decode(flags); 6711cb0ef41Sopenharmony_ci} 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_ciinline void Code::set_can_have_weak_objects(bool value) { 6741cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(kind())); 6751cb0ef41Sopenharmony_ci CodeDataContainer container = code_data_container(kAcquireLoad); 6761cb0ef41Sopenharmony_ci int32_t previous = container.kind_specific_flags(kRelaxedLoad); 6771cb0ef41Sopenharmony_ci int32_t updated = CanHaveWeakObjectsField::update(previous, value); 6781cb0ef41Sopenharmony_ci container.set_kind_specific_flags(updated, kRelaxedStore); 6791cb0ef41Sopenharmony_ci} 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ciinline bool Code::is_promise_rejection() const { 6821cb0ef41Sopenharmony_ci DCHECK(kind() == CodeKind::BUILTIN); 6831cb0ef41Sopenharmony_ci int32_t flags = 6841cb0ef41Sopenharmony_ci code_data_container(kAcquireLoad).kind_specific_flags(kRelaxedLoad); 6851cb0ef41Sopenharmony_ci return IsPromiseRejectionField::decode(flags); 6861cb0ef41Sopenharmony_ci} 6871cb0ef41Sopenharmony_ci 6881cb0ef41Sopenharmony_ciinline void Code::set_is_promise_rejection(bool value) { 6891cb0ef41Sopenharmony_ci DCHECK(kind() == CodeKind::BUILTIN); 6901cb0ef41Sopenharmony_ci CodeDataContainer container = code_data_container(kAcquireLoad); 6911cb0ef41Sopenharmony_ci int32_t previous = container.kind_specific_flags(kRelaxedLoad); 6921cb0ef41Sopenharmony_ci int32_t updated = IsPromiseRejectionField::update(previous, value); 6931cb0ef41Sopenharmony_ci container.set_kind_specific_flags(updated, kRelaxedStore); 6941cb0ef41Sopenharmony_ci} 6951cb0ef41Sopenharmony_ci 6961cb0ef41Sopenharmony_ciinline bool Code::is_off_heap_trampoline() const { 6971cb0ef41Sopenharmony_ci const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset); 6981cb0ef41Sopenharmony_ci return IsOffHeapTrampoline::decode(flags); 6991cb0ef41Sopenharmony_ci} 7001cb0ef41Sopenharmony_ci 7011cb0ef41Sopenharmony_ciinline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() { 7021cb0ef41Sopenharmony_ci if (is_promise_rejection()) return HandlerTable::PROMISE; 7031cb0ef41Sopenharmony_ci return HandlerTable::UNCAUGHT; 7041cb0ef41Sopenharmony_ci} 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ciBuiltin Code::builtin_id() const { 7071cb0ef41Sopenharmony_ci int index = RELAXED_READ_INT_FIELD(*this, kBuiltinIndexOffset); 7081cb0ef41Sopenharmony_ci DCHECK(index == static_cast<int>(Builtin::kNoBuiltinId) || 7091cb0ef41Sopenharmony_ci Builtins::IsBuiltinId(index)); 7101cb0ef41Sopenharmony_ci return static_cast<Builtin>(index); 7111cb0ef41Sopenharmony_ci} 7121cb0ef41Sopenharmony_ci 7131cb0ef41Sopenharmony_civoid Code::set_builtin_id(Builtin builtin) { 7141cb0ef41Sopenharmony_ci DCHECK(builtin == Builtin::kNoBuiltinId || Builtins::IsBuiltinId(builtin)); 7151cb0ef41Sopenharmony_ci RELAXED_WRITE_INT_FIELD(*this, kBuiltinIndexOffset, 7161cb0ef41Sopenharmony_ci static_cast<int>(builtin)); 7171cb0ef41Sopenharmony_ci} 7181cb0ef41Sopenharmony_ci 7191cb0ef41Sopenharmony_cibool Code::is_builtin() const { return builtin_id() != Builtin::kNoBuiltinId; } 7201cb0ef41Sopenharmony_ci 7211cb0ef41Sopenharmony_ciunsigned Code::inlined_bytecode_size() const { 7221cb0ef41Sopenharmony_ci unsigned size = RELAXED_READ_UINT_FIELD(*this, kInlinedBytecodeSizeOffset); 7231cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(kind()) || size == 0); 7241cb0ef41Sopenharmony_ci return size; 7251cb0ef41Sopenharmony_ci} 7261cb0ef41Sopenharmony_ci 7271cb0ef41Sopenharmony_civoid Code::set_inlined_bytecode_size(unsigned size) { 7281cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(kind()) || size == 0); 7291cb0ef41Sopenharmony_ci RELAXED_WRITE_UINT_FIELD(*this, kInlinedBytecodeSizeOffset, size); 7301cb0ef41Sopenharmony_ci} 7311cb0ef41Sopenharmony_ci 7321cb0ef41Sopenharmony_cibool Code::uses_safepoint_table() const { 7331cb0ef41Sopenharmony_ci return is_turbofanned() || is_maglevved() || is_wasm_code(); 7341cb0ef41Sopenharmony_ci} 7351cb0ef41Sopenharmony_ci 7361cb0ef41Sopenharmony_ciint Code::stack_slots() const { 7371cb0ef41Sopenharmony_ci const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset); 7381cb0ef41Sopenharmony_ci const int slots = StackSlotsField::decode(flags); 7391cb0ef41Sopenharmony_ci DCHECK_IMPLIES(!uses_safepoint_table(), slots == 0); 7401cb0ef41Sopenharmony_ci return slots; 7411cb0ef41Sopenharmony_ci} 7421cb0ef41Sopenharmony_ci 7431cb0ef41Sopenharmony_cibool CodeDataContainer::marked_for_deoptimization() const { 7441cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 7451cb0ef41Sopenharmony_ci // kind field is not available on CodeDataContainer when external code space 7461cb0ef41Sopenharmony_ci // is not enabled. 7471cb0ef41Sopenharmony_ci DCHECK(CodeKindCanDeoptimize(kind())); 7481cb0ef41Sopenharmony_ci#endif // V8_EXTERNAL_CODE_SPACE 7491cb0ef41Sopenharmony_ci int32_t flags = kind_specific_flags(kRelaxedLoad); 7501cb0ef41Sopenharmony_ci return Code::MarkedForDeoptimizationField::decode(flags); 7511cb0ef41Sopenharmony_ci} 7521cb0ef41Sopenharmony_ci 7531cb0ef41Sopenharmony_cibool Code::marked_for_deoptimization() const { 7541cb0ef41Sopenharmony_ci DCHECK(CodeKindCanDeoptimize(kind())); 7551cb0ef41Sopenharmony_ci return code_data_container(kAcquireLoad).marked_for_deoptimization(); 7561cb0ef41Sopenharmony_ci} 7571cb0ef41Sopenharmony_ci 7581cb0ef41Sopenharmony_civoid CodeDataContainer::set_marked_for_deoptimization(bool flag) { 7591cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 7601cb0ef41Sopenharmony_ci // kind field is not available on CodeDataContainer when external code space 7611cb0ef41Sopenharmony_ci // is not enabled. 7621cb0ef41Sopenharmony_ci DCHECK(CodeKindCanDeoptimize(kind())); 7631cb0ef41Sopenharmony_ci#endif // V8_EXTERNAL_CODE_SPACE 7641cb0ef41Sopenharmony_ci DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate())); 7651cb0ef41Sopenharmony_ci int32_t previous = kind_specific_flags(kRelaxedLoad); 7661cb0ef41Sopenharmony_ci int32_t updated = Code::MarkedForDeoptimizationField::update(previous, flag); 7671cb0ef41Sopenharmony_ci set_kind_specific_flags(updated, kRelaxedStore); 7681cb0ef41Sopenharmony_ci} 7691cb0ef41Sopenharmony_ci 7701cb0ef41Sopenharmony_civoid Code::set_marked_for_deoptimization(bool flag) { 7711cb0ef41Sopenharmony_ci code_data_container(kAcquireLoad).set_marked_for_deoptimization(flag); 7721cb0ef41Sopenharmony_ci} 7731cb0ef41Sopenharmony_ci 7741cb0ef41Sopenharmony_cibool Code::embedded_objects_cleared() const { 7751cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(kind())); 7761cb0ef41Sopenharmony_ci int32_t flags = 7771cb0ef41Sopenharmony_ci code_data_container(kAcquireLoad).kind_specific_flags(kRelaxedLoad); 7781cb0ef41Sopenharmony_ci return EmbeddedObjectsClearedField::decode(flags); 7791cb0ef41Sopenharmony_ci} 7801cb0ef41Sopenharmony_ci 7811cb0ef41Sopenharmony_civoid Code::set_embedded_objects_cleared(bool flag) { 7821cb0ef41Sopenharmony_ci DCHECK(CodeKindIsOptimizedJSFunction(kind())); 7831cb0ef41Sopenharmony_ci DCHECK_IMPLIES(flag, marked_for_deoptimization()); 7841cb0ef41Sopenharmony_ci CodeDataContainer container = code_data_container(kAcquireLoad); 7851cb0ef41Sopenharmony_ci int32_t previous = container.kind_specific_flags(kRelaxedLoad); 7861cb0ef41Sopenharmony_ci int32_t updated = EmbeddedObjectsClearedField::update(previous, flag); 7871cb0ef41Sopenharmony_ci container.set_kind_specific_flags(updated, kRelaxedStore); 7881cb0ef41Sopenharmony_ci} 7891cb0ef41Sopenharmony_ci 7901cb0ef41Sopenharmony_cibool Code::is_optimized_code() const { 7911cb0ef41Sopenharmony_ci return CodeKindIsOptimizedJSFunction(kind()); 7921cb0ef41Sopenharmony_ci} 7931cb0ef41Sopenharmony_ci 7941cb0ef41Sopenharmony_cibool Code::is_wasm_code() const { return kind() == CodeKind::WASM_FUNCTION; } 7951cb0ef41Sopenharmony_ci 7961cb0ef41Sopenharmony_ciint Code::constant_pool_offset() const { 7971cb0ef41Sopenharmony_ci if (!FLAG_enable_embedded_constant_pool) { 7981cb0ef41Sopenharmony_ci // Redirection needed since the field doesn't exist in this case. 7991cb0ef41Sopenharmony_ci return code_comments_offset(); 8001cb0ef41Sopenharmony_ci } 8011cb0ef41Sopenharmony_ci return ReadField<int>(kConstantPoolOffsetOffset); 8021cb0ef41Sopenharmony_ci} 8031cb0ef41Sopenharmony_ci 8041cb0ef41Sopenharmony_civoid Code::set_constant_pool_offset(int value) { 8051cb0ef41Sopenharmony_ci if (!FLAG_enable_embedded_constant_pool) { 8061cb0ef41Sopenharmony_ci // Redirection needed since the field doesn't exist in this case. 8071cb0ef41Sopenharmony_ci return; 8081cb0ef41Sopenharmony_ci } 8091cb0ef41Sopenharmony_ci DCHECK_LE(value, MetadataSize()); 8101cb0ef41Sopenharmony_ci WriteField<int>(kConstantPoolOffsetOffset, value); 8111cb0ef41Sopenharmony_ci} 8121cb0ef41Sopenharmony_ci 8131cb0ef41Sopenharmony_ciAddress Code::constant_pool() const { 8141cb0ef41Sopenharmony_ci if (!has_constant_pool()) return kNullAddress; 8151cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 8161cb0ef41Sopenharmony_ci ? OffHeapConstantPoolAddress(*this, builtin_id()) 8171cb0ef41Sopenharmony_ci : raw_metadata_start() + constant_pool_offset(); 8181cb0ef41Sopenharmony_ci} 8191cb0ef41Sopenharmony_ci 8201cb0ef41Sopenharmony_ciAddress Code::code_comments() const { 8211cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 8221cb0ef41Sopenharmony_ci ? OffHeapCodeCommentsAddress(*this, builtin_id()) 8231cb0ef41Sopenharmony_ci : raw_metadata_start() + code_comments_offset(); 8241cb0ef41Sopenharmony_ci} 8251cb0ef41Sopenharmony_ci 8261cb0ef41Sopenharmony_ciAddress Code::unwinding_info_start() const { 8271cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 8281cb0ef41Sopenharmony_ci ? OffHeapUnwindingInfoAddress(*this, builtin_id()) 8291cb0ef41Sopenharmony_ci : raw_metadata_start() + unwinding_info_offset(); 8301cb0ef41Sopenharmony_ci} 8311cb0ef41Sopenharmony_ci 8321cb0ef41Sopenharmony_ciAddress Code::unwinding_info_end() const { 8331cb0ef41Sopenharmony_ci return V8_UNLIKELY(is_off_heap_trampoline()) 8341cb0ef41Sopenharmony_ci ? OffHeapMetadataEnd(*this, builtin_id()) 8351cb0ef41Sopenharmony_ci : raw_metadata_end(); 8361cb0ef41Sopenharmony_ci} 8371cb0ef41Sopenharmony_ci 8381cb0ef41Sopenharmony_ciint Code::unwinding_info_size() const { 8391cb0ef41Sopenharmony_ci DCHECK_GE(unwinding_info_end(), unwinding_info_start()); 8401cb0ef41Sopenharmony_ci return static_cast<int>(unwinding_info_end() - unwinding_info_start()); 8411cb0ef41Sopenharmony_ci} 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_cibool Code::has_unwinding_info() const { return unwinding_info_size() > 0; } 8441cb0ef41Sopenharmony_ci 8451cb0ef41Sopenharmony_ciCode Code::GetCodeFromTargetAddress(Address address) { 8461cb0ef41Sopenharmony_ci { 8471cb0ef41Sopenharmony_ci // TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass 8481cb0ef41Sopenharmony_ci // in the current isolate. 8491cb0ef41Sopenharmony_ci Address start = 8501cb0ef41Sopenharmony_ci reinterpret_cast<Address>(Isolate::CurrentEmbeddedBlobCode()); 8511cb0ef41Sopenharmony_ci Address end = start + Isolate::CurrentEmbeddedBlobCodeSize(); 8521cb0ef41Sopenharmony_ci CHECK(address < start || address >= end); 8531cb0ef41Sopenharmony_ci } 8541cb0ef41Sopenharmony_ci 8551cb0ef41Sopenharmony_ci HeapObject code = HeapObject::FromAddress(address - Code::kHeaderSize); 8561cb0ef41Sopenharmony_ci // Unchecked cast because we can't rely on the map currently 8571cb0ef41Sopenharmony_ci // not being a forwarding pointer. 8581cb0ef41Sopenharmony_ci return Code::unchecked_cast(code); 8591cb0ef41Sopenharmony_ci} 8601cb0ef41Sopenharmony_ci 8611cb0ef41Sopenharmony_ciCode Code::GetObjectFromEntryAddress(Address location_of_address) { 8621cb0ef41Sopenharmony_ci Address code_entry = base::Memory<Address>(location_of_address); 8631cb0ef41Sopenharmony_ci HeapObject code = HeapObject::FromAddress(code_entry - Code::kHeaderSize); 8641cb0ef41Sopenharmony_ci // Unchecked cast because we can't rely on the map currently 8651cb0ef41Sopenharmony_ci // not being a forwarding pointer. 8661cb0ef41Sopenharmony_ci return Code::unchecked_cast(code); 8671cb0ef41Sopenharmony_ci} 8681cb0ef41Sopenharmony_ci 8691cb0ef41Sopenharmony_cibool Code::CanContainWeakObjects() { 8701cb0ef41Sopenharmony_ci return is_optimized_code() && can_have_weak_objects(); 8711cb0ef41Sopenharmony_ci} 8721cb0ef41Sopenharmony_ci 8731cb0ef41Sopenharmony_cibool Code::IsWeakObject(HeapObject object) { 8741cb0ef41Sopenharmony_ci return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object)); 8751cb0ef41Sopenharmony_ci} 8761cb0ef41Sopenharmony_ci 8771cb0ef41Sopenharmony_cibool Code::IsWeakObjectInOptimizedCode(HeapObject object) { 8781cb0ef41Sopenharmony_ci Map map = object.map(kAcquireLoad); 8791cb0ef41Sopenharmony_ci InstanceType instance_type = map.instance_type(); 8801cb0ef41Sopenharmony_ci if (InstanceTypeChecker::IsMap(instance_type)) { 8811cb0ef41Sopenharmony_ci return Map::cast(object).CanTransition(); 8821cb0ef41Sopenharmony_ci } 8831cb0ef41Sopenharmony_ci return InstanceTypeChecker::IsPropertyCell(instance_type) || 8841cb0ef41Sopenharmony_ci InstanceTypeChecker::IsJSReceiver(instance_type) || 8851cb0ef41Sopenharmony_ci InstanceTypeChecker::IsContext(instance_type); 8861cb0ef41Sopenharmony_ci} 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_cibool Code::IsWeakObjectInDeoptimizationLiteralArray(Object object) { 8891cb0ef41Sopenharmony_ci // Maps must be strong because they can be used as part of the description for 8901cb0ef41Sopenharmony_ci // how to materialize an object upon deoptimization, in which case it is 8911cb0ef41Sopenharmony_ci // possible to reach the code that requires the Map without anything else 8921cb0ef41Sopenharmony_ci // holding a strong pointer to that Map. 8931cb0ef41Sopenharmony_ci return object.IsHeapObject() && !object.IsMap() && 8941cb0ef41Sopenharmony_ci Code::IsWeakObjectInOptimizedCode(HeapObject::cast(object)); 8951cb0ef41Sopenharmony_ci} 8961cb0ef41Sopenharmony_ci 8971cb0ef41Sopenharmony_cibool Code::IsExecutable() { 8981cb0ef41Sopenharmony_ci return !Builtins::IsBuiltinId(builtin_id()) || !is_off_heap_trampoline() || 8991cb0ef41Sopenharmony_ci Builtins::CodeObjectIsExecutable(builtin_id()); 9001cb0ef41Sopenharmony_ci} 9011cb0ef41Sopenharmony_ci 9021cb0ef41Sopenharmony_ci// This field has to have relaxed atomic accessors because it is accessed in the 9031cb0ef41Sopenharmony_ci// concurrent marker. 9041cb0ef41Sopenharmony_ciSTATIC_ASSERT(FIELD_SIZE(CodeDataContainer::kKindSpecificFlagsOffset) == 9051cb0ef41Sopenharmony_ci kInt32Size); 9061cb0ef41Sopenharmony_ciRELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags, 9071cb0ef41Sopenharmony_ci kKindSpecificFlagsOffset) 9081cb0ef41Sopenharmony_ci 9091cb0ef41Sopenharmony_ci#if defined(V8_TARGET_LITTLE_ENDIAN) 9101cb0ef41Sopenharmony_cistatic_assert(!V8_EXTERNAL_CODE_SPACE_BOOL || 9111cb0ef41Sopenharmony_ci (CodeDataContainer::kCodeCageBaseUpper32BitsOffset == 9121cb0ef41Sopenharmony_ci CodeDataContainer::kCodeOffset + kTaggedSize), 9131cb0ef41Sopenharmony_ci "CodeDataContainer::code field layout requires updating " 9141cb0ef41Sopenharmony_ci "for little endian architectures"); 9151cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_BIG_ENDIAN) 9161cb0ef41Sopenharmony_cistatic_assert(!V8_EXTERNAL_CODE_SPACE_BOOL, 9171cb0ef41Sopenharmony_ci "CodeDataContainer::code field layout requires updating " 9181cb0ef41Sopenharmony_ci "for big endian architectures"); 9191cb0ef41Sopenharmony_ci#endif 9201cb0ef41Sopenharmony_ci 9211cb0ef41Sopenharmony_ciObject CodeDataContainer::raw_code() const { 9221cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = code_cage_base(); 9231cb0ef41Sopenharmony_ci return CodeDataContainer::raw_code(cage_base); 9241cb0ef41Sopenharmony_ci} 9251cb0ef41Sopenharmony_ci 9261cb0ef41Sopenharmony_ciObject CodeDataContainer::raw_code(PtrComprCageBase cage_base) const { 9271cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 9281cb0ef41Sopenharmony_ci Object value = TaggedField<Object, kCodeOffset>::load(cage_base, *this); 9291cb0ef41Sopenharmony_ci return value; 9301cb0ef41Sopenharmony_ci} 9311cb0ef41Sopenharmony_ci 9321cb0ef41Sopenharmony_civoid CodeDataContainer::set_raw_code(Object value, WriteBarrierMode mode) { 9331cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 9341cb0ef41Sopenharmony_ci TaggedField<Object, kCodeOffset>::store(*this, value); 9351cb0ef41Sopenharmony_ci CONDITIONAL_WRITE_BARRIER(*this, kCodeOffset, value, mode); 9361cb0ef41Sopenharmony_ci} 9371cb0ef41Sopenharmony_ci 9381cb0ef41Sopenharmony_ciObject CodeDataContainer::raw_code(RelaxedLoadTag tag) const { 9391cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = code_cage_base(tag); 9401cb0ef41Sopenharmony_ci return CodeDataContainer::raw_code(cage_base, tag); 9411cb0ef41Sopenharmony_ci} 9421cb0ef41Sopenharmony_ci 9431cb0ef41Sopenharmony_ciObject CodeDataContainer::raw_code(PtrComprCageBase cage_base, 9441cb0ef41Sopenharmony_ci RelaxedLoadTag) const { 9451cb0ef41Sopenharmony_ci Object value = 9461cb0ef41Sopenharmony_ci TaggedField<Object, kCodeOffset>::Relaxed_Load(cage_base, *this); 9471cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 9481cb0ef41Sopenharmony_ci return value; 9491cb0ef41Sopenharmony_ci} 9501cb0ef41Sopenharmony_ci 9511cb0ef41Sopenharmony_ciACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset) 9521cb0ef41Sopenharmony_ci 9531cb0ef41Sopenharmony_ciPtrComprCageBase CodeDataContainer::code_cage_base() const { 9541cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 9551cb0ef41Sopenharmony_ci // TODO(v8:10391): consider protecting this value with the sandbox. 9561cb0ef41Sopenharmony_ci Address code_cage_base_hi = 9571cb0ef41Sopenharmony_ci ReadField<Tagged_t>(kCodeCageBaseUpper32BitsOffset); 9581cb0ef41Sopenharmony_ci return PtrComprCageBase(code_cage_base_hi << 32); 9591cb0ef41Sopenharmony_ci#else 9601cb0ef41Sopenharmony_ci return GetPtrComprCageBase(*this); 9611cb0ef41Sopenharmony_ci#endif 9621cb0ef41Sopenharmony_ci} 9631cb0ef41Sopenharmony_ci 9641cb0ef41Sopenharmony_civoid CodeDataContainer::set_code_cage_base(Address code_cage_base) { 9651cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 9661cb0ef41Sopenharmony_ci Tagged_t code_cage_base_hi = static_cast<Tagged_t>(code_cage_base >> 32); 9671cb0ef41Sopenharmony_ci WriteField<Tagged_t>(kCodeCageBaseUpper32BitsOffset, code_cage_base_hi); 9681cb0ef41Sopenharmony_ci#else 9691cb0ef41Sopenharmony_ci UNREACHABLE(); 9701cb0ef41Sopenharmony_ci#endif 9711cb0ef41Sopenharmony_ci} 9721cb0ef41Sopenharmony_ci 9731cb0ef41Sopenharmony_ciPtrComprCageBase CodeDataContainer::code_cage_base(RelaxedLoadTag) const { 9741cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 9751cb0ef41Sopenharmony_ci // TODO(v8:10391): consider protecting this value with the sandbox. 9761cb0ef41Sopenharmony_ci Address code_cage_base_hi = 9771cb0ef41Sopenharmony_ci Relaxed_ReadField<Tagged_t>(kCodeCageBaseUpper32BitsOffset); 9781cb0ef41Sopenharmony_ci return PtrComprCageBase(code_cage_base_hi << 32); 9791cb0ef41Sopenharmony_ci#else 9801cb0ef41Sopenharmony_ci return GetPtrComprCageBase(*this); 9811cb0ef41Sopenharmony_ci#endif 9821cb0ef41Sopenharmony_ci} 9831cb0ef41Sopenharmony_ci 9841cb0ef41Sopenharmony_civoid CodeDataContainer::set_code_cage_base(Address code_cage_base, 9851cb0ef41Sopenharmony_ci RelaxedStoreTag) { 9861cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 9871cb0ef41Sopenharmony_ci Tagged_t code_cage_base_hi = static_cast<Tagged_t>(code_cage_base >> 32); 9881cb0ef41Sopenharmony_ci Relaxed_WriteField<Tagged_t>(kCodeCageBaseUpper32BitsOffset, 9891cb0ef41Sopenharmony_ci code_cage_base_hi); 9901cb0ef41Sopenharmony_ci#else 9911cb0ef41Sopenharmony_ci UNREACHABLE(); 9921cb0ef41Sopenharmony_ci#endif 9931cb0ef41Sopenharmony_ci} 9941cb0ef41Sopenharmony_ci 9951cb0ef41Sopenharmony_civoid CodeDataContainer::AllocateExternalPointerEntries(Isolate* isolate) { 9961cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 9971cb0ef41Sopenharmony_ci InitExternalPointerField(kCodeEntryPointOffset, isolate, kCodeEntryPointTag); 9981cb0ef41Sopenharmony_ci} 9991cb0ef41Sopenharmony_ci 10001cb0ef41Sopenharmony_ciCode CodeDataContainer::code() const { 10011cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = code_cage_base(); 10021cb0ef41Sopenharmony_ci return CodeDataContainer::code(cage_base); 10031cb0ef41Sopenharmony_ci} 10041cb0ef41Sopenharmony_ciCode CodeDataContainer::code(PtrComprCageBase cage_base) const { 10051cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10061cb0ef41Sopenharmony_ci return Code::cast(raw_code(cage_base)); 10071cb0ef41Sopenharmony_ci} 10081cb0ef41Sopenharmony_ci 10091cb0ef41Sopenharmony_ciCode CodeDataContainer::code(RelaxedLoadTag tag) const { 10101cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = code_cage_base(tag); 10111cb0ef41Sopenharmony_ci return CodeDataContainer::code(cage_base, tag); 10121cb0ef41Sopenharmony_ci} 10131cb0ef41Sopenharmony_ci 10141cb0ef41Sopenharmony_ciCode CodeDataContainer::code(PtrComprCageBase cage_base, 10151cb0ef41Sopenharmony_ci RelaxedLoadTag tag) const { 10161cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10171cb0ef41Sopenharmony_ci return Code::cast(raw_code(cage_base, tag)); 10181cb0ef41Sopenharmony_ci} 10191cb0ef41Sopenharmony_ci 10201cb0ef41Sopenharmony_ciDEF_GETTER(CodeDataContainer, code_entry_point, Address) { 10211cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10221cb0ef41Sopenharmony_ci Isolate* isolate = GetIsolateForSandbox(*this); 10231cb0ef41Sopenharmony_ci return ReadExternalPointerField(kCodeEntryPointOffset, isolate, 10241cb0ef41Sopenharmony_ci kCodeEntryPointTag); 10251cb0ef41Sopenharmony_ci} 10261cb0ef41Sopenharmony_ci 10271cb0ef41Sopenharmony_civoid CodeDataContainer::set_code_entry_point(Isolate* isolate, Address value) { 10281cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10291cb0ef41Sopenharmony_ci WriteExternalPointerField(kCodeEntryPointOffset, isolate, value, 10301cb0ef41Sopenharmony_ci kCodeEntryPointTag); 10311cb0ef41Sopenharmony_ci} 10321cb0ef41Sopenharmony_ci 10331cb0ef41Sopenharmony_civoid CodeDataContainer::SetCodeAndEntryPoint(Isolate* isolate_for_sandbox, 10341cb0ef41Sopenharmony_ci Code code, WriteBarrierMode mode) { 10351cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10361cb0ef41Sopenharmony_ci set_raw_code(code, mode); 10371cb0ef41Sopenharmony_ci set_code_entry_point(isolate_for_sandbox, code.InstructionStart()); 10381cb0ef41Sopenharmony_ci} 10391cb0ef41Sopenharmony_ci 10401cb0ef41Sopenharmony_civoid CodeDataContainer::UpdateCodeEntryPoint(Isolate* isolate_for_sandbox, 10411cb0ef41Sopenharmony_ci Code code) { 10421cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10431cb0ef41Sopenharmony_ci DCHECK_EQ(raw_code(), code); 10441cb0ef41Sopenharmony_ci set_code_entry_point(isolate_for_sandbox, code.InstructionStart()); 10451cb0ef41Sopenharmony_ci} 10461cb0ef41Sopenharmony_ci 10471cb0ef41Sopenharmony_ciAddress CodeDataContainer::InstructionStart() const { 10481cb0ef41Sopenharmony_ci return code_entry_point(); 10491cb0ef41Sopenharmony_ci} 10501cb0ef41Sopenharmony_ci 10511cb0ef41Sopenharmony_ciAddress CodeDataContainer::raw_instruction_start() { 10521cb0ef41Sopenharmony_ci return code_entry_point(); 10531cb0ef41Sopenharmony_ci} 10541cb0ef41Sopenharmony_ci 10551cb0ef41Sopenharmony_ciAddress CodeDataContainer::entry() const { return code_entry_point(); } 10561cb0ef41Sopenharmony_ci 10571cb0ef41Sopenharmony_civoid CodeDataContainer::clear_padding() { 10581cb0ef41Sopenharmony_ci memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0, 10591cb0ef41Sopenharmony_ci kSize - kUnalignedSize); 10601cb0ef41Sopenharmony_ci} 10611cb0ef41Sopenharmony_ci 10621cb0ef41Sopenharmony_ciRELAXED_UINT16_ACCESSORS(CodeDataContainer, flags, kFlagsOffset) 10631cb0ef41Sopenharmony_ci 10641cb0ef41Sopenharmony_ci// Ensure builtin_id field fits into int16_t, so that we can rely on sign 10651cb0ef41Sopenharmony_ci// extension to convert int16_t{-1} to kNoBuiltinId. 10661cb0ef41Sopenharmony_ci// If the asserts fail, update the code that use kBuiltinIdOffset below. 10671cb0ef41Sopenharmony_ciSTATIC_ASSERT(static_cast<int>(Builtin::kNoBuiltinId) == -1); 10681cb0ef41Sopenharmony_ciSTATIC_ASSERT(Builtins::kBuiltinCount < std::numeric_limits<int16_t>::max()); 10691cb0ef41Sopenharmony_ci 10701cb0ef41Sopenharmony_civoid CodeDataContainer::initialize_flags(CodeKind kind, Builtin builtin_id) { 10711cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10721cb0ef41Sopenharmony_ci uint16_t value = KindField::encode(kind); 10731cb0ef41Sopenharmony_ci set_flags(value, kRelaxedStore); 10741cb0ef41Sopenharmony_ci 10751cb0ef41Sopenharmony_ci WriteField<int16_t>(kBuiltinIdOffset, static_cast<int16_t>(builtin_id)); 10761cb0ef41Sopenharmony_ci} 10771cb0ef41Sopenharmony_ci 10781cb0ef41Sopenharmony_ci#ifdef V8_EXTERNAL_CODE_SPACE 10791cb0ef41Sopenharmony_ci 10801cb0ef41Sopenharmony_ciCodeKind CodeDataContainer::kind() const { 10811cb0ef41Sopenharmony_ci return KindField::decode(flags(kRelaxedLoad)); 10821cb0ef41Sopenharmony_ci} 10831cb0ef41Sopenharmony_ci 10841cb0ef41Sopenharmony_ciBuiltin CodeDataContainer::builtin_id() const { 10851cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10861cb0ef41Sopenharmony_ci // Rely on sign-extension when converting int16_t to int to preserve 10871cb0ef41Sopenharmony_ci // kNoBuiltinId value. 10881cb0ef41Sopenharmony_ci STATIC_ASSERT(static_cast<int>(static_cast<int16_t>(Builtin::kNoBuiltinId)) == 10891cb0ef41Sopenharmony_ci static_cast<int>(Builtin::kNoBuiltinId)); 10901cb0ef41Sopenharmony_ci int value = ReadField<int16_t>(kBuiltinIdOffset); 10911cb0ef41Sopenharmony_ci return static_cast<Builtin>(value); 10921cb0ef41Sopenharmony_ci} 10931cb0ef41Sopenharmony_ci 10941cb0ef41Sopenharmony_cibool CodeDataContainer::is_builtin() const { 10951cb0ef41Sopenharmony_ci CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); 10961cb0ef41Sopenharmony_ci return builtin_id() != Builtin::kNoBuiltinId; 10971cb0ef41Sopenharmony_ci} 10981cb0ef41Sopenharmony_ci 10991cb0ef41Sopenharmony_cibool CodeDataContainer::is_optimized_code() const { 11001cb0ef41Sopenharmony_ci return CodeKindIsOptimizedJSFunction(kind()); 11011cb0ef41Sopenharmony_ci} 11021cb0ef41Sopenharmony_ci 11031cb0ef41Sopenharmony_ciinline bool CodeDataContainer::is_interpreter_trampoline_builtin() const { 11041cb0ef41Sopenharmony_ci return IsInterpreterTrampolineBuiltin(builtin_id()); 11051cb0ef41Sopenharmony_ci} 11061cb0ef41Sopenharmony_ci 11071cb0ef41Sopenharmony_ci// 11081cb0ef41Sopenharmony_ci// A collection of getters and predicates that forward queries to associated 11091cb0ef41Sopenharmony_ci// Code object. 11101cb0ef41Sopenharmony_ci// 11111cb0ef41Sopenharmony_ci 11121cb0ef41Sopenharmony_ci#define DEF_PRIMITIVE_FORWARDING_CDC_GETTER(name, type) \ 11131cb0ef41Sopenharmony_ci type CodeDataContainer::name() const { return FromCodeT(*this).name(); } 11141cb0ef41Sopenharmony_ci 11151cb0ef41Sopenharmony_ci#define DEF_FORWARDING_CDC_GETTER(name, type) \ 11161cb0ef41Sopenharmony_ci DEF_GETTER(CodeDataContainer, name, type) { \ 11171cb0ef41Sopenharmony_ci return FromCodeT(*this).name(cage_base); \ 11181cb0ef41Sopenharmony_ci } 11191cb0ef41Sopenharmony_ci 11201cb0ef41Sopenharmony_ciDEF_PRIMITIVE_FORWARDING_CDC_GETTER(is_maglevved, bool) 11211cb0ef41Sopenharmony_ciDEF_PRIMITIVE_FORWARDING_CDC_GETTER(is_turbofanned, bool) 11221cb0ef41Sopenharmony_ciDEF_PRIMITIVE_FORWARDING_CDC_GETTER(is_off_heap_trampoline, bool) 11231cb0ef41Sopenharmony_ci 11241cb0ef41Sopenharmony_ciDEF_FORWARDING_CDC_GETTER(deoptimization_data, FixedArray) 11251cb0ef41Sopenharmony_ciDEF_FORWARDING_CDC_GETTER(bytecode_or_interpreter_data, HeapObject) 11261cb0ef41Sopenharmony_ciDEF_FORWARDING_CDC_GETTER(source_position_table, ByteArray) 11271cb0ef41Sopenharmony_ciDEF_FORWARDING_CDC_GETTER(bytecode_offset_table, ByteArray) 11281cb0ef41Sopenharmony_ci 11291cb0ef41Sopenharmony_ci#undef DEF_PRIMITIVE_FORWARDING_CDC_GETTER 11301cb0ef41Sopenharmony_ci#undef DEF_FORWARDING_CDC_GETTER 11311cb0ef41Sopenharmony_ci 11321cb0ef41Sopenharmony_ci#endif // V8_EXTERNAL_CODE_SPACE 11331cb0ef41Sopenharmony_ci 11341cb0ef41Sopenharmony_cibyte BytecodeArray::get(int index) const { 11351cb0ef41Sopenharmony_ci DCHECK(index >= 0 && index < this->length()); 11361cb0ef41Sopenharmony_ci return ReadField<byte>(kHeaderSize + index * kCharSize); 11371cb0ef41Sopenharmony_ci} 11381cb0ef41Sopenharmony_ci 11391cb0ef41Sopenharmony_civoid BytecodeArray::set(int index, byte value) { 11401cb0ef41Sopenharmony_ci DCHECK(index >= 0 && index < this->length()); 11411cb0ef41Sopenharmony_ci WriteField<byte>(kHeaderSize + index * kCharSize, value); 11421cb0ef41Sopenharmony_ci} 11431cb0ef41Sopenharmony_ci 11441cb0ef41Sopenharmony_civoid BytecodeArray::set_frame_size(int32_t frame_size) { 11451cb0ef41Sopenharmony_ci DCHECK_GE(frame_size, 0); 11461cb0ef41Sopenharmony_ci DCHECK(IsAligned(frame_size, kSystemPointerSize)); 11471cb0ef41Sopenharmony_ci WriteField<int32_t>(kFrameSizeOffset, frame_size); 11481cb0ef41Sopenharmony_ci} 11491cb0ef41Sopenharmony_ci 11501cb0ef41Sopenharmony_ciint32_t BytecodeArray::frame_size() const { 11511cb0ef41Sopenharmony_ci return ReadField<int32_t>(kFrameSizeOffset); 11521cb0ef41Sopenharmony_ci} 11531cb0ef41Sopenharmony_ci 11541cb0ef41Sopenharmony_ciint BytecodeArray::register_count() const { 11551cb0ef41Sopenharmony_ci return static_cast<int>(frame_size()) / kSystemPointerSize; 11561cb0ef41Sopenharmony_ci} 11571cb0ef41Sopenharmony_ci 11581cb0ef41Sopenharmony_civoid BytecodeArray::set_parameter_count(int32_t number_of_parameters) { 11591cb0ef41Sopenharmony_ci DCHECK_GE(number_of_parameters, 0); 11601cb0ef41Sopenharmony_ci // Parameter count is stored as the size on stack of the parameters to allow 11611cb0ef41Sopenharmony_ci // it to be used directly by generated code. 11621cb0ef41Sopenharmony_ci WriteField<int32_t>(kParameterSizeOffset, 11631cb0ef41Sopenharmony_ci (number_of_parameters << kSystemPointerSizeLog2)); 11641cb0ef41Sopenharmony_ci} 11651cb0ef41Sopenharmony_ci 11661cb0ef41Sopenharmony_ciinterpreter::Register BytecodeArray::incoming_new_target_or_generator_register() 11671cb0ef41Sopenharmony_ci const { 11681cb0ef41Sopenharmony_ci int32_t register_operand = 11691cb0ef41Sopenharmony_ci ReadField<int32_t>(kIncomingNewTargetOrGeneratorRegisterOffset); 11701cb0ef41Sopenharmony_ci if (register_operand == 0) { 11711cb0ef41Sopenharmony_ci return interpreter::Register::invalid_value(); 11721cb0ef41Sopenharmony_ci } else { 11731cb0ef41Sopenharmony_ci return interpreter::Register::FromOperand(register_operand); 11741cb0ef41Sopenharmony_ci } 11751cb0ef41Sopenharmony_ci} 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_civoid BytecodeArray::set_incoming_new_target_or_generator_register( 11781cb0ef41Sopenharmony_ci interpreter::Register incoming_new_target_or_generator_register) { 11791cb0ef41Sopenharmony_ci if (!incoming_new_target_or_generator_register.is_valid()) { 11801cb0ef41Sopenharmony_ci WriteField<int32_t>(kIncomingNewTargetOrGeneratorRegisterOffset, 0); 11811cb0ef41Sopenharmony_ci } else { 11821cb0ef41Sopenharmony_ci DCHECK(incoming_new_target_or_generator_register.index() < 11831cb0ef41Sopenharmony_ci register_count()); 11841cb0ef41Sopenharmony_ci DCHECK_NE(0, incoming_new_target_or_generator_register.ToOperand()); 11851cb0ef41Sopenharmony_ci WriteField<int32_t>(kIncomingNewTargetOrGeneratorRegisterOffset, 11861cb0ef41Sopenharmony_ci incoming_new_target_or_generator_register.ToOperand()); 11871cb0ef41Sopenharmony_ci } 11881cb0ef41Sopenharmony_ci} 11891cb0ef41Sopenharmony_ci 11901cb0ef41Sopenharmony_ciint BytecodeArray::osr_urgency() const { 11911cb0ef41Sopenharmony_ci return OsrUrgencyBits::decode(osr_urgency_and_install_target()); 11921cb0ef41Sopenharmony_ci} 11931cb0ef41Sopenharmony_ci 11941cb0ef41Sopenharmony_civoid BytecodeArray::set_osr_urgency(int urgency) { 11951cb0ef41Sopenharmony_ci DCHECK(0 <= urgency && urgency <= BytecodeArray::kMaxOsrUrgency); 11961cb0ef41Sopenharmony_ci STATIC_ASSERT(BytecodeArray::kMaxOsrUrgency <= OsrUrgencyBits::kMax); 11971cb0ef41Sopenharmony_ci uint32_t value = osr_urgency_and_install_target(); 11981cb0ef41Sopenharmony_ci set_osr_urgency_and_install_target(OsrUrgencyBits::update(value, urgency)); 11991cb0ef41Sopenharmony_ci} 12001cb0ef41Sopenharmony_ci 12011cb0ef41Sopenharmony_ciBytecodeArray::Age BytecodeArray::bytecode_age() const { 12021cb0ef41Sopenharmony_ci // Bytecode is aged by the concurrent marker. 12031cb0ef41Sopenharmony_ci static_assert(kBytecodeAgeSize == kUInt16Size); 12041cb0ef41Sopenharmony_ci return static_cast<Age>(RELAXED_READ_INT16_FIELD(*this, kBytecodeAgeOffset)); 12051cb0ef41Sopenharmony_ci} 12061cb0ef41Sopenharmony_ci 12071cb0ef41Sopenharmony_civoid BytecodeArray::reset_osr_urgency() { set_osr_urgency(0); } 12081cb0ef41Sopenharmony_ci 12091cb0ef41Sopenharmony_civoid BytecodeArray::RequestOsrAtNextOpportunity() { 12101cb0ef41Sopenharmony_ci set_osr_urgency(kMaxOsrUrgency); 12111cb0ef41Sopenharmony_ci} 12121cb0ef41Sopenharmony_ci 12131cb0ef41Sopenharmony_ciint BytecodeArray::osr_install_target() { 12141cb0ef41Sopenharmony_ci return OsrInstallTargetBits::decode(osr_urgency_and_install_target()); 12151cb0ef41Sopenharmony_ci} 12161cb0ef41Sopenharmony_ci 12171cb0ef41Sopenharmony_civoid BytecodeArray::set_osr_install_target(BytecodeOffset jump_loop_offset) { 12181cb0ef41Sopenharmony_ci DCHECK_LE(jump_loop_offset.ToInt(), length()); 12191cb0ef41Sopenharmony_ci set_osr_urgency_and_install_target(OsrInstallTargetBits::update( 12201cb0ef41Sopenharmony_ci osr_urgency_and_install_target(), OsrInstallTargetFor(jump_loop_offset))); 12211cb0ef41Sopenharmony_ci} 12221cb0ef41Sopenharmony_ci 12231cb0ef41Sopenharmony_civoid BytecodeArray::reset_osr_install_target() { 12241cb0ef41Sopenharmony_ci uint32_t value = osr_urgency_and_install_target(); 12251cb0ef41Sopenharmony_ci set_osr_urgency_and_install_target( 12261cb0ef41Sopenharmony_ci OsrInstallTargetBits::update(value, kNoOsrInstallTarget)); 12271cb0ef41Sopenharmony_ci} 12281cb0ef41Sopenharmony_ci 12291cb0ef41Sopenharmony_civoid BytecodeArray::reset_osr_urgency_and_install_target() { 12301cb0ef41Sopenharmony_ci set_osr_urgency_and_install_target(OsrUrgencyBits::encode(0) | 12311cb0ef41Sopenharmony_ci OsrInstallTargetBits::encode(0)); 12321cb0ef41Sopenharmony_ci} 12331cb0ef41Sopenharmony_ci 12341cb0ef41Sopenharmony_civoid BytecodeArray::set_bytecode_age(BytecodeArray::Age age) { 12351cb0ef41Sopenharmony_ci DCHECK_GE(age, kFirstBytecodeAge); 12361cb0ef41Sopenharmony_ci DCHECK_LE(age, kLastBytecodeAge); 12371cb0ef41Sopenharmony_ci static_assert(kLastBytecodeAge <= kMaxInt16); 12381cb0ef41Sopenharmony_ci static_assert(kBytecodeAgeSize == kUInt16Size); 12391cb0ef41Sopenharmony_ci // Bytecode is aged by the concurrent marker. 12401cb0ef41Sopenharmony_ci RELAXED_WRITE_INT16_FIELD(*this, kBytecodeAgeOffset, 12411cb0ef41Sopenharmony_ci static_cast<int16_t>(age)); 12421cb0ef41Sopenharmony_ci} 12431cb0ef41Sopenharmony_ci 12441cb0ef41Sopenharmony_ciint32_t BytecodeArray::parameter_count() const { 12451cb0ef41Sopenharmony_ci // Parameter count is stored as the size on stack of the parameters to allow 12461cb0ef41Sopenharmony_ci // it to be used directly by generated code. 12471cb0ef41Sopenharmony_ci return ReadField<int32_t>(kParameterSizeOffset) >> kSystemPointerSizeLog2; 12481cb0ef41Sopenharmony_ci} 12491cb0ef41Sopenharmony_ci 12501cb0ef41Sopenharmony_civoid BytecodeArray::clear_padding() { 12511cb0ef41Sopenharmony_ci int data_size = kHeaderSize + length(); 12521cb0ef41Sopenharmony_ci memset(reinterpret_cast<void*>(address() + data_size), 0, 12531cb0ef41Sopenharmony_ci SizeFor(length()) - data_size); 12541cb0ef41Sopenharmony_ci} 12551cb0ef41Sopenharmony_ci 12561cb0ef41Sopenharmony_ciAddress BytecodeArray::GetFirstBytecodeAddress() { 12571cb0ef41Sopenharmony_ci return ptr() - kHeapObjectTag + kHeaderSize; 12581cb0ef41Sopenharmony_ci} 12591cb0ef41Sopenharmony_ci 12601cb0ef41Sopenharmony_cibool BytecodeArray::HasSourcePositionTable() const { 12611cb0ef41Sopenharmony_ci Object maybe_table = source_position_table(kAcquireLoad); 12621cb0ef41Sopenharmony_ci return !(maybe_table.IsUndefined() || DidSourcePositionGenerationFail()); 12631cb0ef41Sopenharmony_ci} 12641cb0ef41Sopenharmony_ci 12651cb0ef41Sopenharmony_cibool BytecodeArray::DidSourcePositionGenerationFail() const { 12661cb0ef41Sopenharmony_ci return source_position_table(kAcquireLoad).IsException(); 12671cb0ef41Sopenharmony_ci} 12681cb0ef41Sopenharmony_ci 12691cb0ef41Sopenharmony_civoid BytecodeArray::SetSourcePositionsFailedToCollect() { 12701cb0ef41Sopenharmony_ci set_source_position_table(GetReadOnlyRoots().exception(), kReleaseStore); 12711cb0ef41Sopenharmony_ci} 12721cb0ef41Sopenharmony_ci 12731cb0ef41Sopenharmony_ciByteArray BytecodeArray::SourcePositionTable() const { 12741cb0ef41Sopenharmony_ci // WARNING: This function may be called from a background thread, hence 12751cb0ef41Sopenharmony_ci // changes to how it accesses the heap can easily lead to bugs. 12761cb0ef41Sopenharmony_ci Object maybe_table = source_position_table(kAcquireLoad); 12771cb0ef41Sopenharmony_ci if (maybe_table.IsByteArray()) return ByteArray::cast(maybe_table); 12781cb0ef41Sopenharmony_ci ReadOnlyRoots roots = GetReadOnlyRoots(); 12791cb0ef41Sopenharmony_ci DCHECK(maybe_table.IsUndefined(roots) || maybe_table.IsException(roots)); 12801cb0ef41Sopenharmony_ci return roots.empty_byte_array(); 12811cb0ef41Sopenharmony_ci} 12821cb0ef41Sopenharmony_ci 12831cb0ef41Sopenharmony_ciint BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); } 12841cb0ef41Sopenharmony_ci 12851cb0ef41Sopenharmony_ciint BytecodeArray::SizeIncludingMetadata() { 12861cb0ef41Sopenharmony_ci int size = BytecodeArraySize(); 12871cb0ef41Sopenharmony_ci size += constant_pool().Size(); 12881cb0ef41Sopenharmony_ci size += handler_table().Size(); 12891cb0ef41Sopenharmony_ci ByteArray table = SourcePositionTable(); 12901cb0ef41Sopenharmony_ci if (table.length() != 0) { 12911cb0ef41Sopenharmony_ci size += table.Size(); 12921cb0ef41Sopenharmony_ci } 12931cb0ef41Sopenharmony_ci return size; 12941cb0ef41Sopenharmony_ci} 12951cb0ef41Sopenharmony_ci 12961cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(TranslationByteArray, TranslationArray) 12971cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) 12981cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(LiteralArray, DeoptimizationLiteralArray) 12991cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(OsrBytecodeOffset, Smi) 13001cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(OsrPcOffset, Smi) 13011cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(OptimizationId, Smi) 13021cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(InliningPositions, PodArray<InliningPosition>) 13031cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(DeoptExitStart, Smi) 13041cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(EagerDeoptCount, Smi) 13051cb0ef41Sopenharmony_ciDEFINE_DEOPT_ELEMENT_ACCESSORS(LazyDeoptCount, Smi) 13061cb0ef41Sopenharmony_ci 13071cb0ef41Sopenharmony_ciDEFINE_DEOPT_ENTRY_ACCESSORS(BytecodeOffsetRaw, Smi) 13081cb0ef41Sopenharmony_ciDEFINE_DEOPT_ENTRY_ACCESSORS(TranslationIndex, Smi) 13091cb0ef41Sopenharmony_ciDEFINE_DEOPT_ENTRY_ACCESSORS(Pc, Smi) 13101cb0ef41Sopenharmony_ci#ifdef DEBUG 13111cb0ef41Sopenharmony_ciDEFINE_DEOPT_ENTRY_ACCESSORS(NodeId, Smi) 13121cb0ef41Sopenharmony_ci#endif // DEBUG 13131cb0ef41Sopenharmony_ci 13141cb0ef41Sopenharmony_ciBytecodeOffset DeoptimizationData::GetBytecodeOffset(int i) { 13151cb0ef41Sopenharmony_ci return BytecodeOffset(BytecodeOffsetRaw(i).value()); 13161cb0ef41Sopenharmony_ci} 13171cb0ef41Sopenharmony_ci 13181cb0ef41Sopenharmony_civoid DeoptimizationData::SetBytecodeOffset(int i, BytecodeOffset value) { 13191cb0ef41Sopenharmony_ci SetBytecodeOffsetRaw(i, Smi::FromInt(value.ToInt())); 13201cb0ef41Sopenharmony_ci} 13211cb0ef41Sopenharmony_ci 13221cb0ef41Sopenharmony_ciint DeoptimizationData::DeoptCount() { 13231cb0ef41Sopenharmony_ci return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize; 13241cb0ef41Sopenharmony_ci} 13251cb0ef41Sopenharmony_ci 13261cb0ef41Sopenharmony_ciinline DeoptimizationLiteralArray::DeoptimizationLiteralArray(Address ptr) 13271cb0ef41Sopenharmony_ci : WeakFixedArray(ptr) { 13281cb0ef41Sopenharmony_ci // No type check is possible beyond that for WeakFixedArray. 13291cb0ef41Sopenharmony_ci} 13301cb0ef41Sopenharmony_ci 13311cb0ef41Sopenharmony_ciinline Object DeoptimizationLiteralArray::get(int index) const { 13321cb0ef41Sopenharmony_ci return get(GetPtrComprCageBase(*this), index); 13331cb0ef41Sopenharmony_ci} 13341cb0ef41Sopenharmony_ci 13351cb0ef41Sopenharmony_ciinline Object DeoptimizationLiteralArray::get(PtrComprCageBase cage_base, 13361cb0ef41Sopenharmony_ci int index) const { 13371cb0ef41Sopenharmony_ci MaybeObject maybe = Get(cage_base, index); 13381cb0ef41Sopenharmony_ci 13391cb0ef41Sopenharmony_ci // Slots in the DeoptimizationLiteralArray should only be cleared when there 13401cb0ef41Sopenharmony_ci // is no possible code path that could need that slot. This works because the 13411cb0ef41Sopenharmony_ci // weakly-held deoptimization literals are basically local variables that 13421cb0ef41Sopenharmony_ci // TurboFan has decided not to keep on the stack. Thus, if the deoptimization 13431cb0ef41Sopenharmony_ci // literal goes away, then whatever code needed it should be unreachable. The 13441cb0ef41Sopenharmony_ci // exception is currently running Code: in that case, the deoptimization 13451cb0ef41Sopenharmony_ci // literals array might be the only thing keeping the target object alive. 13461cb0ef41Sopenharmony_ci // Thus, when a Code is running, we strongly mark all of its deoptimization 13471cb0ef41Sopenharmony_ci // literals. 13481cb0ef41Sopenharmony_ci CHECK(!maybe.IsCleared()); 13491cb0ef41Sopenharmony_ci 13501cb0ef41Sopenharmony_ci return maybe.GetHeapObjectOrSmi(); 13511cb0ef41Sopenharmony_ci} 13521cb0ef41Sopenharmony_ci 13531cb0ef41Sopenharmony_ciinline void DeoptimizationLiteralArray::set(int index, Object value) { 13541cb0ef41Sopenharmony_ci MaybeObject maybe = MaybeObject::FromObject(value); 13551cb0ef41Sopenharmony_ci if (Code::IsWeakObjectInDeoptimizationLiteralArray(value)) { 13561cb0ef41Sopenharmony_ci maybe = MaybeObject::MakeWeak(maybe); 13571cb0ef41Sopenharmony_ci } 13581cb0ef41Sopenharmony_ci Set(index, maybe); 13591cb0ef41Sopenharmony_ci} 13601cb0ef41Sopenharmony_ci 13611cb0ef41Sopenharmony_ci} // namespace internal 13621cb0ef41Sopenharmony_ci} // namespace v8 13631cb0ef41Sopenharmony_ci 13641cb0ef41Sopenharmony_ci#include "src/objects/object-macros-undef.h" 13651cb0ef41Sopenharmony_ci 13661cb0ef41Sopenharmony_ci#endif // V8_OBJECTS_CODE_INL_H_ 1367