• 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/turbo-assembler.h"
6 
7 #include "src/builtins/builtins.h"
8 #include "src/builtins/constants-table-builder.h"
9 #include "src/heap/heap-inl.h"
10 #include "src/lsan.h"
11 #include "src/snapshot/serializer-common.h"
12 
13 namespace v8 {
14 namespace internal {
15 
TurboAssemblerBase(Isolate * isolate,const AssemblerOptions & options,void * buffer,int buffer_size,CodeObjectRequired create_code_object)16 TurboAssemblerBase::TurboAssemblerBase(Isolate* isolate,
17                                        const AssemblerOptions& options,
18                                        void* buffer, int buffer_size,
19                                        CodeObjectRequired create_code_object)
20     : Assembler(options, buffer, buffer_size), 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   Heap::RootListIndex root_index;
36   if (isolate()->heap()->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()->ShouldLoadConstantsFromRootList());
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 
75     // Encode as an index into the external reference table stored on the
76     // isolate.
77     ExternalReferenceEncoder encoder(isolate());
78     ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
79     CHECK(!v.is_from_api());
80 
81     LoadRootRelative(destination,
82                      RootRegisterOffsetForExternalReferenceIndex(v.index()));
83   }
84 }
85 
86 // static
RootRegisterOffset(Heap::RootListIndex root_index)87 int32_t TurboAssemblerBase::RootRegisterOffset(Heap::RootListIndex root_index) {
88   return (root_index << kPointerSizeLog2) - kRootRegisterBias;
89 }
90 
91 // static
RootRegisterOffsetForExternalReferenceIndex(int reference_index)92 int32_t TurboAssemblerBase::RootRegisterOffsetForExternalReferenceIndex(
93     int reference_index) {
94   return Heap::roots_to_external_reference_table_offset() - kRootRegisterBias +
95          ExternalReferenceTable::OffsetOfEntry(reference_index);
96 }
97 
98 // static
RootRegisterOffsetForExternalReference(Isolate * isolate,const ExternalReference & reference)99 intptr_t TurboAssemblerBase::RootRegisterOffsetForExternalReference(
100     Isolate* isolate, const ExternalReference& reference) {
101   return static_cast<intptr_t>(reference.address()) - kRootRegisterBias -
102          reinterpret_cast<intptr_t>(isolate->heap()->roots_array_start());
103 }
104 
105 // static
IsAddressableThroughRootRegister(Isolate * isolate,const ExternalReference & reference)106 bool TurboAssemblerBase::IsAddressableThroughRootRegister(
107     Isolate* isolate, const ExternalReference& reference) {
108   Address start = reinterpret_cast<Address>(isolate);
109   Address end = isolate->heap()->root_register_addressable_end();
110   Address address = reference.address();
111   return start <= address && address < end;
112 }
113 
114 // static
RootRegisterOffsetForBuiltinIndex(int builtin_index)115 int32_t TurboAssemblerBase::RootRegisterOffsetForBuiltinIndex(
116     int builtin_index) {
117   return Heap::roots_to_builtins_offset() - kRootRegisterBias +
118          builtin_index * kPointerSize;
119 }
120 
RecordCommentForOffHeapTrampoline(int builtin_index)121 void TurboAssemblerBase::RecordCommentForOffHeapTrampoline(int builtin_index) {
122   if (!FLAG_code_comments) return;
123   size_t len = strlen("-- Inlined Trampoline to  --") +
124                strlen(Builtins::name(builtin_index)) + 1;
125   Vector<char> buffer = Vector<char>::New(static_cast<int>(len));
126   char* buffer_start = buffer.start();
127   LSAN_IGNORE_OBJECT(buffer_start);
128   SNPrintF(buffer, "-- Inlined Trampoline to %s --",
129            Builtins::name(builtin_index));
130   RecordComment(buffer_start);
131 }
132 
133 }  // namespace internal
134 }  // namespace v8
135