• 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/execution/isolate-data.h"
11 #include "src/execution/isolate-inl.h"
12 
13 namespace v8 {
14 namespace internal {
15 
TurboAssemblerBase(Isolate * isolate,const AssemblerOptions & options,CodeObjectRequired create_code_object,std::unique_ptr<AssemblerBuffer> buffer)16 TurboAssemblerBase::TurboAssemblerBase(Isolate* isolate,
17                                        const AssemblerOptions& options,
18                                        CodeObjectRequired create_code_object,
19                                        std::unique_ptr<AssemblerBuffer> buffer)
20     : Assembler(options, std::move(buffer)), isolate_(isolate) {
21   if (create_code_object == CodeObjectRequired::kYes) {
22     code_object_ = Handle<HeapObject>::New(
23         ReadOnlyRoots(isolate).self_reference_marker(), isolate);
24   }
25 }
26 
IndirectLoadConstant(Register destination,Handle<HeapObject> object)27 void TurboAssemblerBase::IndirectLoadConstant(Register destination,
28                                               Handle<HeapObject> object) {
29   CHECK(root_array_available_);
30 
31   // Before falling back to the (fairly slow) lookup from the constants table,
32   // check if any of the fast paths can be applied.
33 
34   int builtin_index;
35   RootIndex root_index;
36   if (isolate()->roots_table().IsRootHandle(object, &root_index)) {
37     // Roots are loaded relative to the root register.
38     LoadRoot(destination, root_index);
39   } else if (isolate()->builtins()->IsBuiltinHandle(object, &builtin_index)) {
40     // Similar to roots, builtins may be loaded from the builtins table.
41     LoadRootRelative(destination,
42                      RootRegisterOffsetForBuiltinIndex(builtin_index));
43   } else if (object.is_identical_to(code_object_) &&
44              Builtins::IsBuiltinId(maybe_builtin_index_)) {
45     // The self-reference loaded through Codevalue() may also be a builtin
46     // and thus viable for a fast load.
47     LoadRootRelative(destination,
48                      RootRegisterOffsetForBuiltinIndex(maybe_builtin_index_));
49   } else {
50     CHECK(isolate()->IsGeneratingEmbeddedBuiltins());
51     // Ensure the given object is in the builtins constants table and fetch its
52     // index.
53     BuiltinsConstantsTableBuilder* builder =
54         isolate()->builtins_constants_table_builder();
55     uint32_t index = builder->AddObject(object);
56 
57     // Slow load from the constants table.
58     LoadFromConstantsTable(destination, index);
59   }
60 }
61 
IndirectLoadExternalReference(Register destination,ExternalReference reference)62 void TurboAssemblerBase::IndirectLoadExternalReference(
63     Register destination, ExternalReference reference) {
64   CHECK(root_array_available_);
65 
66   if (IsAddressableThroughRootRegister(isolate(), reference)) {
67     // Some external references can be efficiently loaded as an offset from
68     // kRootRegister.
69     intptr_t offset =
70         RootRegisterOffsetForExternalReference(isolate(), reference);
71     LoadRootRegisterOffset(destination, offset);
72   } else {
73     // Otherwise, do a memory load from the external reference table.
74     LoadRootRelative(
75         destination,
76         RootRegisterOffsetForExternalReferenceTableEntry(isolate(), reference));
77   }
78 }
79 
80 // static
RootRegisterOffsetForRootIndex(RootIndex root_index)81 int32_t TurboAssemblerBase::RootRegisterOffsetForRootIndex(
82     RootIndex root_index) {
83   return IsolateData::root_slot_offset(root_index);
84 }
85 
86 // static
RootRegisterOffsetForBuiltinIndex(int builtin_index)87 int32_t TurboAssemblerBase::RootRegisterOffsetForBuiltinIndex(
88     int builtin_index) {
89   return IsolateData::builtin_slot_offset(builtin_index);
90 }
91 
92 // static
RootRegisterOffsetForExternalReference(Isolate * isolate,const ExternalReference & reference)93 intptr_t TurboAssemblerBase::RootRegisterOffsetForExternalReference(
94     Isolate* isolate, const ExternalReference& reference) {
95   return static_cast<intptr_t>(reference.address() - isolate->isolate_root());
96 }
97 
98 // static
RootRegisterOffsetForExternalReferenceTableEntry(Isolate * isolate,const ExternalReference & reference)99 int32_t TurboAssemblerBase::RootRegisterOffsetForExternalReferenceTableEntry(
100     Isolate* isolate, const ExternalReference& reference) {
101   // Encode as an index into the external reference table stored on the
102   // isolate.
103   ExternalReferenceEncoder encoder(isolate);
104   ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
105   CHECK(!v.is_from_api());
106 
107   return IsolateData::external_reference_table_offset() +
108          ExternalReferenceTable::OffsetOfEntry(v.index());
109 }
110 
111 // static
IsAddressableThroughRootRegister(Isolate * isolate,const ExternalReference & reference)112 bool TurboAssemblerBase::IsAddressableThroughRootRegister(
113     Isolate* isolate, const ExternalReference& reference) {
114   Address address = reference.address();
115   return isolate->root_register_addressable_region().contains(address);
116 }
117 
RecordCommentForOffHeapTrampoline(int builtin_index)118 void TurboAssemblerBase::RecordCommentForOffHeapTrampoline(int builtin_index) {
119   if (!FLAG_code_comments) return;
120   std::ostringstream str;
121   str << "-- Inlined Trampoline to " << Builtins::name(builtin_index) << " --";
122   RecordComment(str.str().c_str());
123 }
124 
125 }  // namespace internal
126 }  // namespace v8
127