11cb0ef41Sopenharmony_ci// Copyright 2018 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/codegen/turbo-assembler.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h" 81cb0ef41Sopenharmony_ci#include "src/builtins/constants-table-builder.h" 91cb0ef41Sopenharmony_ci#include "src/codegen/external-reference-encoder.h" 101cb0ef41Sopenharmony_ci#include "src/common/globals.h" 111cb0ef41Sopenharmony_ci#include "src/execution/isolate-data.h" 121cb0ef41Sopenharmony_ci#include "src/execution/isolate-inl.h" 131cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/embedded-data-inl.h" 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cinamespace v8 { 161cb0ef41Sopenharmony_cinamespace internal { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciTurboAssemblerBase::TurboAssemblerBase(Isolate* isolate, 191cb0ef41Sopenharmony_ci const AssemblerOptions& options, 201cb0ef41Sopenharmony_ci CodeObjectRequired create_code_object, 211cb0ef41Sopenharmony_ci std::unique_ptr<AssemblerBuffer> buffer) 221cb0ef41Sopenharmony_ci : Assembler(options, std::move(buffer)), isolate_(isolate) { 231cb0ef41Sopenharmony_ci if (create_code_object == CodeObjectRequired::kYes) { 241cb0ef41Sopenharmony_ci code_object_ = Handle<HeapObject>::New( 251cb0ef41Sopenharmony_ci ReadOnlyRoots(isolate).self_reference_marker(), isolate); 261cb0ef41Sopenharmony_ci } 271cb0ef41Sopenharmony_ci} 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciAddress TurboAssemblerBase::BuiltinEntry(Builtin builtin) { 301cb0ef41Sopenharmony_ci DCHECK(Builtins::IsBuiltinId(builtin)); 311cb0ef41Sopenharmony_ci if (isolate_ != nullptr) { 321cb0ef41Sopenharmony_ci Address entry = 331cb0ef41Sopenharmony_ci isolate_->builtin_entry_table()[static_cast<int32_t>(builtin)]; 341cb0ef41Sopenharmony_ci DCHECK_EQ(entry, EmbeddedData::FromBlob(isolate_).InstructionStartOfBuiltin( 351cb0ef41Sopenharmony_ci builtin)); 361cb0ef41Sopenharmony_ci return entry; 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci EmbeddedData d = EmbeddedData::FromBlob(); 391cb0ef41Sopenharmony_ci return d.InstructionStartOfBuiltin(builtin); 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_civoid TurboAssemblerBase::IndirectLoadConstant(Register destination, 431cb0ef41Sopenharmony_ci Handle<HeapObject> object) { 441cb0ef41Sopenharmony_ci CHECK(root_array_available_); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // Before falling back to the (fairly slow) lookup from the constants table, 471cb0ef41Sopenharmony_ci // check if any of the fast paths can be applied. 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci Builtin builtin; 501cb0ef41Sopenharmony_ci RootIndex root_index; 511cb0ef41Sopenharmony_ci if (isolate()->roots_table().IsRootHandle(object, &root_index)) { 521cb0ef41Sopenharmony_ci // Roots are loaded relative to the root register. 531cb0ef41Sopenharmony_ci LoadRoot(destination, root_index); 541cb0ef41Sopenharmony_ci } else if (isolate()->builtins()->IsBuiltinHandle(object, &builtin)) { 551cb0ef41Sopenharmony_ci // Similar to roots, builtins may be loaded from the builtins table. 561cb0ef41Sopenharmony_ci LoadRootRelative(destination, RootRegisterOffsetForBuiltin(builtin)); 571cb0ef41Sopenharmony_ci } else if (object.is_identical_to(code_object_) && 581cb0ef41Sopenharmony_ci Builtins::IsBuiltinId(maybe_builtin_)) { 591cb0ef41Sopenharmony_ci // The self-reference loaded through Codevalue() may also be a builtin 601cb0ef41Sopenharmony_ci // and thus viable for a fast load. 611cb0ef41Sopenharmony_ci LoadRootRelative(destination, RootRegisterOffsetForBuiltin(maybe_builtin_)); 621cb0ef41Sopenharmony_ci } else { 631cb0ef41Sopenharmony_ci CHECK(isolate()->IsGeneratingEmbeddedBuiltins()); 641cb0ef41Sopenharmony_ci // Ensure the given object is in the builtins constants table and fetch its 651cb0ef41Sopenharmony_ci // index. 661cb0ef41Sopenharmony_ci BuiltinsConstantsTableBuilder* builder = 671cb0ef41Sopenharmony_ci isolate()->builtins_constants_table_builder(); 681cb0ef41Sopenharmony_ci uint32_t index = builder->AddObject(object); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Slow load from the constants table. 711cb0ef41Sopenharmony_ci LoadFromConstantsTable(destination, index); 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_civoid TurboAssemblerBase::IndirectLoadExternalReference( 761cb0ef41Sopenharmony_ci Register destination, ExternalReference reference) { 771cb0ef41Sopenharmony_ci CHECK(root_array_available_); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci if (IsAddressableThroughRootRegister(isolate(), reference)) { 801cb0ef41Sopenharmony_ci // Some external references can be efficiently loaded as an offset from 811cb0ef41Sopenharmony_ci // kRootRegister. 821cb0ef41Sopenharmony_ci intptr_t offset = 831cb0ef41Sopenharmony_ci RootRegisterOffsetForExternalReference(isolate(), reference); 841cb0ef41Sopenharmony_ci LoadRootRegisterOffset(destination, offset); 851cb0ef41Sopenharmony_ci } else { 861cb0ef41Sopenharmony_ci // Otherwise, do a memory load from the external reference table. 871cb0ef41Sopenharmony_ci LoadRootRelative( 881cb0ef41Sopenharmony_ci destination, 891cb0ef41Sopenharmony_ci RootRegisterOffsetForExternalReferenceTableEntry(isolate(), reference)); 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci// static 941cb0ef41Sopenharmony_ciint32_t TurboAssemblerBase::RootRegisterOffsetForRootIndex( 951cb0ef41Sopenharmony_ci RootIndex root_index) { 961cb0ef41Sopenharmony_ci return IsolateData::root_slot_offset(root_index); 971cb0ef41Sopenharmony_ci} 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci// static 1001cb0ef41Sopenharmony_ciint32_t TurboAssemblerBase::RootRegisterOffsetForBuiltin(Builtin builtin) { 1011cb0ef41Sopenharmony_ci return IsolateData::BuiltinSlotOffset(builtin); 1021cb0ef41Sopenharmony_ci} 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci// static 1051cb0ef41Sopenharmony_ciintptr_t TurboAssemblerBase::RootRegisterOffsetForExternalReference( 1061cb0ef41Sopenharmony_ci Isolate* isolate, const ExternalReference& reference) { 1071cb0ef41Sopenharmony_ci return static_cast<intptr_t>(reference.address() - isolate->isolate_root()); 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci// static 1111cb0ef41Sopenharmony_ciint32_t TurboAssemblerBase::RootRegisterOffsetForExternalReferenceTableEntry( 1121cb0ef41Sopenharmony_ci Isolate* isolate, const ExternalReference& reference) { 1131cb0ef41Sopenharmony_ci // Encode as an index into the external reference table stored on the 1141cb0ef41Sopenharmony_ci // isolate. 1151cb0ef41Sopenharmony_ci ExternalReferenceEncoder encoder(isolate); 1161cb0ef41Sopenharmony_ci ExternalReferenceEncoder::Value v = encoder.Encode(reference.address()); 1171cb0ef41Sopenharmony_ci CHECK(!v.is_from_api()); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci return IsolateData::external_reference_table_offset() + 1201cb0ef41Sopenharmony_ci ExternalReferenceTable::OffsetOfEntry(v.index()); 1211cb0ef41Sopenharmony_ci} 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci// static 1241cb0ef41Sopenharmony_cibool TurboAssemblerBase::IsAddressableThroughRootRegister( 1251cb0ef41Sopenharmony_ci Isolate* isolate, const ExternalReference& reference) { 1261cb0ef41Sopenharmony_ci Address address = reference.address(); 1271cb0ef41Sopenharmony_ci return isolate->root_register_addressable_region().contains(address); 1281cb0ef41Sopenharmony_ci} 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci} // namespace internal 1311cb0ef41Sopenharmony_ci} // namespace v8 132