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