• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/codegen/turbo-assembler.h"
6 
7 #include "src/builtins/builtins.h"
8 #include "src/builtins/constants-table-builder.h"
9 #include "src/codegen/external-reference-encoder.h"
10 #include "src/common/globals.h"
11 #include "src/execution/isolate-data.h"
12 #include "src/execution/isolate-inl.h"
13 #include "src/snapshot/embedded/embedded-data-inl.h"
14 
15 namespace v8 {
16 namespace internal {
17 
TurboAssemblerBase(Isolate * isolate,const AssemblerOptions & options,CodeObjectRequired create_code_object,std::unique_ptr<AssemblerBuffer> buffer)18 TurboAssemblerBase::TurboAssemblerBase(Isolate* isolate,
19                                        const AssemblerOptions& options,
20                                        CodeObjectRequired create_code_object,
21                                        std::unique_ptr<AssemblerBuffer> buffer)
22     : Assembler(options, std::move(buffer)), isolate_(isolate) {
23   if (create_code_object == CodeObjectRequired::kYes) {
24     code_object_ = Handle<HeapObject>::New(
25         ReadOnlyRoots(isolate).self_reference_marker(), isolate);
26   }
27 }
28 
BuiltinEntry(Builtin builtin)29 Address TurboAssemblerBase::BuiltinEntry(Builtin builtin) {
30   DCHECK(Builtins::IsBuiltinId(builtin));
31   if (isolate_ != nullptr) {
32     Address entry =
33         isolate_->builtin_entry_table()[static_cast<int32_t>(builtin)];
34     DCHECK_EQ(entry, EmbeddedData::FromBlob(isolate_).InstructionStartOfBuiltin(
35                          builtin));
36     return entry;
37   }
38   EmbeddedData d = EmbeddedData::FromBlob();
39   return d.InstructionStartOfBuiltin(builtin);
40 }
41 
IndirectLoadConstant(Register destination,Handle<HeapObject> object)42 void TurboAssemblerBase::IndirectLoadConstant(Register destination,
43                                               Handle<HeapObject> object) {
44   CHECK(root_array_available_);
45 
46   // Before falling back to the (fairly slow) lookup from the constants table,
47   // check if any of the fast paths can be applied.
48 
49   Builtin builtin;
50   RootIndex root_index;
51   if (isolate()->roots_table().IsRootHandle(object, &root_index)) {
52     // Roots are loaded relative to the root register.
53     LoadRoot(destination, root_index);
54   } else if (isolate()->builtins()->IsBuiltinHandle(object, &builtin)) {
55     // Similar to roots, builtins may be loaded from the builtins table.
56     LoadRootRelative(destination, RootRegisterOffsetForBuiltin(builtin));
57   } else if (object.is_identical_to(code_object_) &&
58              Builtins::IsBuiltinId(maybe_builtin_)) {
59     // The self-reference loaded through Codevalue() may also be a builtin
60     // and thus viable for a fast load.
61     LoadRootRelative(destination, RootRegisterOffsetForBuiltin(maybe_builtin_));
62   } else {
63     CHECK(isolate()->IsGeneratingEmbeddedBuiltins());
64     // Ensure the given object is in the builtins constants table and fetch its
65     // index.
66     BuiltinsConstantsTableBuilder* builder =
67         isolate()->builtins_constants_table_builder();
68     uint32_t index = builder->AddObject(object);
69 
70     // Slow load from the constants table.
71     LoadFromConstantsTable(destination, index);
72   }
73 }
74 
IndirectLoadExternalReference(Register destination,ExternalReference reference)75 void TurboAssemblerBase::IndirectLoadExternalReference(
76     Register destination, ExternalReference reference) {
77   CHECK(root_array_available_);
78 
79   if (IsAddressableThroughRootRegister(isolate(), reference)) {
80     // Some external references can be efficiently loaded as an offset from
81     // kRootRegister.
82     intptr_t offset =
83         RootRegisterOffsetForExternalReference(isolate(), reference);
84     LoadRootRegisterOffset(destination, offset);
85   } else {
86     // Otherwise, do a memory load from the external reference table.
87     LoadRootRelative(
88         destination,
89         RootRegisterOffsetForExternalReferenceTableEntry(isolate(), reference));
90   }
91 }
92 
93 // static
RootRegisterOffsetForRootIndex(RootIndex root_index)94 int32_t TurboAssemblerBase::RootRegisterOffsetForRootIndex(
95     RootIndex root_index) {
96   return IsolateData::root_slot_offset(root_index);
97 }
98 
99 // static
RootRegisterOffsetForBuiltin(Builtin builtin)100 int32_t TurboAssemblerBase::RootRegisterOffsetForBuiltin(Builtin builtin) {
101   return IsolateData::BuiltinSlotOffset(builtin);
102 }
103 
104 // static
RootRegisterOffsetForExternalReference(Isolate * isolate,const ExternalReference & reference)105 intptr_t TurboAssemblerBase::RootRegisterOffsetForExternalReference(
106     Isolate* isolate, const ExternalReference& reference) {
107   return static_cast<intptr_t>(reference.address() - isolate->isolate_root());
108 }
109 
110 // static
RootRegisterOffsetForExternalReferenceTableEntry(Isolate * isolate,const ExternalReference & reference)111 int32_t TurboAssemblerBase::RootRegisterOffsetForExternalReferenceTableEntry(
112     Isolate* isolate, const ExternalReference& reference) {
113   // Encode as an index into the external reference table stored on the
114   // isolate.
115   ExternalReferenceEncoder encoder(isolate);
116   ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
117   CHECK(!v.is_from_api());
118 
119   return IsolateData::external_reference_table_offset() +
120          ExternalReferenceTable::OffsetOfEntry(v.index());
121 }
122 
123 // static
IsAddressableThroughRootRegister(Isolate * isolate,const ExternalReference & reference)124 bool TurboAssemblerBase::IsAddressableThroughRootRegister(
125     Isolate* isolate, const ExternalReference& reference) {
126   Address address = reference.address();
127   return isolate->root_register_addressable_region().contains(address);
128 }
129 
130 }  // namespace internal
131 }  // namespace v8
132