Line data Source code
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/isolate-data.h"
10 : #include "src/isolate-inl.h"
11 : #include "src/snapshot/serializer-common.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 35149512 : TurboAssemblerBase::TurboAssemblerBase(Isolate* isolate,
17 : const AssemblerOptions& options,
18 : CodeObjectRequired create_code_object,
19 : std::unique_ptr<AssemblerBuffer> buffer)
20 105449338 : : Assembler(options, std::move(buffer)), isolate_(isolate) {
21 35149913 : if (create_code_object == CodeObjectRequired::kYes) {
22 : code_object_ = Handle<HeapObject>::New(
23 314198 : ReadOnlyRoots(isolate).self_reference_marker(), isolate);
24 : }
25 35149913 : }
26 :
27 48048 : void TurboAssemblerBase::IndirectLoadConstant(Register destination,
28 87136 : Handle<HeapObject> object) {
29 48048 : 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 48048 : if (isolate()->roots_table().IsRootHandle(object, &root_index)) {
37 : // Roots are loaded relative to the root register.
38 112 : LoadRoot(destination, root_index);
39 47936 : } else if (isolate()->builtins()->IsBuiltinHandle(object, &builtin_index)) {
40 : // Similar to roots, builtins may be loaded from the builtins table.
41 : LoadRootRelative(destination,
42 16352 : RootRegisterOffsetForBuiltinIndex(builtin_index));
43 40432 : } else if (object.is_identical_to(code_object_) &&
44 672 : 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 1344 : RootRegisterOffsetForBuiltinIndex(maybe_builtin_index_));
49 : } else {
50 39088 : 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 39088 : uint32_t index = builder->AddObject(object);
56 :
57 : // Slow load from the constants table.
58 39088 : LoadFromConstantsTable(destination, index);
59 : }
60 48048 : }
61 :
62 809484 : void TurboAssemblerBase::IndirectLoadExternalReference(
63 809484 : Register destination, ExternalReference reference) {
64 809484 : CHECK(root_array_available_);
65 :
66 809484 : 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 18816 : LoadRootRegisterOffset(destination, offset);
72 : } else {
73 : // Otherwise, do a memory load from the external reference table.
74 : LoadRootRelative(
75 : destination,
76 790668 : RootRegisterOffsetForExternalReferenceTableEntry(isolate(), reference));
77 : }
78 809484 : }
79 :
80 : // static
81 3441219 : int32_t TurboAssemblerBase::RootRegisterOffsetForRootIndex(
82 : RootIndex root_index) {
83 3441219 : return IsolateData::root_slot_offset(root_index);
84 : }
85 :
86 : // static
87 0 : int32_t TurboAssemblerBase::RootRegisterOffsetForBuiltinIndex(
88 : int builtin_index) {
89 0 : return IsolateData::builtin_slot_offset(builtin_index);
90 : }
91 :
92 : // static
93 584529 : intptr_t TurboAssemblerBase::RootRegisterOffsetForExternalReference(
94 : Isolate* isolate, const ExternalReference& reference) {
95 603345 : return static_cast<intptr_t>(reference.address() - isolate->isolate_root());
96 : }
97 :
98 : // static
99 791284 : 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 791284 : ExternalReferenceEncoder encoder(isolate);
104 791284 : ExternalReferenceEncoder::Value v = encoder.Encode(reference.address());
105 791284 : CHECK(!v.is_from_api());
106 :
107 791284 : return IsolateData::external_reference_table_offset() +
108 791284 : ExternalReferenceTable::OffsetOfEntry(v.index());
109 : }
110 :
111 : // static
112 92848 : bool TurboAssemblerBase::IsAddressableThroughRootRegister(
113 : Isolate* isolate, const ExternalReference& reference) {
114 : Address address = reference.address();
115 92848 : return isolate->root_register_addressable_region().contains(address);
116 : }
117 :
118 4657789 : void TurboAssemblerBase::RecordCommentForOffHeapTrampoline(int builtin_index) {
119 9314054 : if (!FLAG_code_comments) return;
120 1524 : std::ostringstream str;
121 1524 : str << "-- Inlined Trampoline to " << Builtins::name(builtin_index) << " --";
122 3048 : RecordComment(str.str().c_str());
123 : }
124 :
125 : } // namespace internal
126 178779 : } // namespace v8
|