Line data Source code
1 : // Copyright 2017 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/setup-isolate.h"
6 :
7 : #include "src/builtins/builtins.h"
8 : #include "src/code-events.h"
9 : #include "src/compiler/code-assembler.h"
10 : #include "src/interface-descriptors.h"
11 : #include "src/isolate.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : // Forward declarations for C++ builtins.
17 : #define FORWARD_DECLARE(Name) \
18 : Object* Builtin_##Name(int argc, Object** args, Isolate* isolate);
19 : BUILTIN_LIST_C(FORWARD_DECLARE)
20 :
21 : namespace {
22 : void PostBuildProfileAndTracing(Isolate* isolate, Code* code,
23 : const char* name) {
24 27520 : PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG,
25 : AbstractCode::cast(code), name));
26 : #ifdef ENABLE_DISASSEMBLER
27 : if (FLAG_print_builtin_code) {
28 : CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
29 : OFStream os(trace_scope.file());
30 : os << "Builtin: " << name << "\n";
31 : code->Disassemble(name, os);
32 : os << "\n";
33 : }
34 : #endif
35 : }
36 :
37 : typedef void (*MacroAssemblerGenerator)(MacroAssembler*);
38 : typedef void (*CodeAssemblerGenerator)(compiler::CodeAssemblerState*);
39 :
40 3827 : Code* BuildWithMacroAssembler(Isolate* isolate,
41 : MacroAssemblerGenerator generator,
42 : Code::Flags flags, const char* s_name) {
43 : HandleScope scope(isolate);
44 : const size_t buffer_size = 32 * KB;
45 : byte buffer[buffer_size]; // NOLINT(runtime/arrays)
46 3827 : MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes);
47 : DCHECK(!masm.has_frame());
48 3827 : generator(&masm);
49 : CodeDesc desc;
50 3827 : masm.GetCode(&desc);
51 : Handle<Code> code =
52 3827 : isolate->factory()->NewCode(desc, flags, masm.CodeObject());
53 : PostBuildProfileAndTracing(isolate, *code, s_name);
54 3827 : return *code;
55 : }
56 :
57 9804 : Code* BuildAdaptor(Isolate* isolate, Address builtin_address,
58 : Builtins::ExitFrameType exit_frame_type, Code::Flags flags,
59 : const char* name) {
60 : HandleScope scope(isolate);
61 : const size_t buffer_size = 32 * KB;
62 : byte buffer[buffer_size]; // NOLINT(runtime/arrays)
63 9804 : MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes);
64 : DCHECK(!masm.has_frame());
65 9804 : Builtins::Generate_Adaptor(&masm, builtin_address, exit_frame_type);
66 : CodeDesc desc;
67 9804 : masm.GetCode(&desc);
68 : Handle<Code> code =
69 9804 : isolate->factory()->NewCode(desc, flags, masm.CodeObject());
70 : PostBuildProfileAndTracing(isolate, *code, name);
71 9804 : return *code;
72 : }
73 :
74 : // Builder for builtins implemented in TurboFan with JS linkage.
75 16254 : Code* BuildWithCodeStubAssemblerJS(Isolate* isolate,
76 : CodeAssemblerGenerator generator, int argc,
77 : Code::Flags flags, const char* name) {
78 : HandleScope scope(isolate);
79 16254 : Zone zone(isolate->allocator(), ZONE_NAME);
80 : const int argc_with_recv =
81 8127 : (argc == SharedFunctionInfo::kDontAdaptArgumentsSentinel) ? 0 : argc + 1;
82 : compiler::CodeAssemblerState state(isolate, &zone, argc_with_recv, flags,
83 16254 : name);
84 8127 : generator(&state);
85 8127 : Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
86 : PostBuildProfileAndTracing(isolate, *code, name);
87 8127 : return *code;
88 : }
89 :
90 : // Builder for builtins implemented in TurboFan with CallStub linkage.
91 11524 : Code* BuildWithCodeStubAssemblerCS(Isolate* isolate,
92 : CodeAssemblerGenerator generator,
93 : CallDescriptors::Key interface_descriptor,
94 : Code::Flags flags, const char* name,
95 : int result_size) {
96 : HandleScope scope(isolate);
97 11524 : Zone zone(isolate->allocator(), ZONE_NAME);
98 : // The interface descriptor with given key must be initialized at this point
99 : // and this construction just queries the details from the descriptors table.
100 : CallInterfaceDescriptor descriptor(isolate, interface_descriptor);
101 : // Ensure descriptor is already initialized.
102 : DCHECK_LE(0, descriptor.GetRegisterParameterCount());
103 : compiler::CodeAssemblerState state(isolate, &zone, descriptor, flags, name,
104 11524 : result_size);
105 5762 : generator(&state);
106 5762 : Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
107 : PostBuildProfileAndTracing(isolate, *code, name);
108 5762 : return *code;
109 : }
110 : } // anonymous namespace
111 :
112 0 : void SetupIsolateDelegate::AddBuiltin(Builtins* builtins, int index,
113 : Code* code) {
114 27520 : builtins->builtins_[index] = code;
115 : code->set_builtin_index(index);
116 0 : }
117 :
118 43 : void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
119 : Builtins* builtins = isolate->builtins();
120 : DCHECK(!builtins->initialized_);
121 :
122 : // Create a scope for the handles in the builtins.
123 : HandleScope scope(isolate);
124 :
125 : int index = 0;
126 : const Code::Flags kBuiltinFlags = Code::ComputeFlags(Code::BUILTIN);
127 : Code* code;
128 : #define BUILD_CPP(Name) \
129 : code = BuildAdaptor(isolate, FUNCTION_ADDR(Builtin_##Name), \
130 : Builtins::BUILTIN_EXIT, kBuiltinFlags, #Name); \
131 : AddBuiltin(builtins, index++, code);
132 : #define BUILD_API(Name) \
133 : code = BuildAdaptor(isolate, FUNCTION_ADDR(Builtin_##Name), Builtins::EXIT, \
134 : kBuiltinFlags, #Name); \
135 : AddBuiltin(builtins, index++, code);
136 : #define BUILD_TFJ(Name, Argc, ...) \
137 : code = BuildWithCodeStubAssemblerJS(isolate, &Builtins::Generate_##Name, \
138 : Argc, kBuiltinFlags, #Name); \
139 : AddBuiltin(builtins, index++, code);
140 : #define BUILD_TFC(Name, InterfaceDescriptor, result_size) \
141 : { InterfaceDescriptor##Descriptor descriptor(isolate); } \
142 : code = BuildWithCodeStubAssemblerCS(isolate, &Builtins::Generate_##Name, \
143 : CallDescriptors::InterfaceDescriptor, \
144 : kBuiltinFlags, #Name, result_size); \
145 : AddBuiltin(builtins, index++, code);
146 : #define BUILD_TFS(Name, ...) \
147 : /* Return size for generic TF builtins (stub linkage) is always 1. */ \
148 : code = BuildWithCodeStubAssemblerCS(isolate, &Builtins::Generate_##Name, \
149 : CallDescriptors::Name, kBuiltinFlags, \
150 : #Name, 1); \
151 : AddBuiltin(builtins, index++, code);
152 : #define BUILD_TFH(Name, Kind, Extra, InterfaceDescriptor) \
153 : { InterfaceDescriptor##Descriptor descriptor(isolate); } \
154 : /* Return size for IC builtins/handlers is always 1. */ \
155 : code = BuildWithCodeStubAssemblerCS(isolate, &Builtins::Generate_##Name, \
156 : CallDescriptors::InterfaceDescriptor, \
157 : Code::ComputeFlags(Code::Kind, Extra), \
158 : #Name, 1); \
159 : AddBuiltin(builtins, index++, code);
160 : #define BUILD_ASM(Name) \
161 : code = BuildWithMacroAssembler(isolate, Builtins::Generate_##Name, \
162 : kBuiltinFlags, #Name); \
163 : AddBuiltin(builtins, index++, code);
164 :
165 32465 : BUILTIN_LIST(BUILD_CPP, BUILD_API, BUILD_TFJ, BUILD_TFC, BUILD_TFS, BUILD_TFH,
166 : BUILD_ASM, BUILD_ASM);
167 :
168 : #undef BUILD_CPP
169 : #undef BUILD_API
170 : #undef BUILD_TFJ
171 : #undef BUILD_TFC
172 : #undef BUILD_TFS
173 : #undef BUILD_TFH
174 : #undef BUILD_ASM
175 : CHECK_EQ(Builtins::builtin_count, index);
176 :
177 : #define SET_PROMISE_REJECTION_PREDICTION(Name) \
178 : Code::cast(builtins->builtins_[Builtins::k##Name]) \
179 : ->set_is_promise_rejection(true);
180 :
181 688 : BUILTIN_PROMISE_REJECTION_PREDICTION_LIST(SET_PROMISE_REJECTION_PREDICTION)
182 : #undef SET_PROMISE_REJECTION_PREDICTION
183 :
184 : #define SET_EXCEPTION_CAUGHT_PREDICTION(Name) \
185 : Code::cast(builtins->builtins_[Builtins::k##Name]) \
186 : ->set_is_exception_caught(true);
187 :
188 43 : BUILTIN_EXCEPTION_CAUGHT_PREDICTION_LIST(SET_EXCEPTION_CAUGHT_PREDICTION)
189 : #undef SET_EXCEPTION_CAUGHT_PREDICTION
190 :
191 : #define SET_CODE_NON_TAGGED_PARAMS(Name) \
192 : Code::cast(builtins->builtins_[Builtins::k##Name]) \
193 : ->set_has_tagged_params(false);
194 :
195 43 : BUILTINS_WITH_UNTAGGED_PARAMS(SET_CODE_NON_TAGGED_PARAMS)
196 : #undef SET_CODE_NON_TAGGED_PARAMS
197 :
198 : isolate->builtins()->MarkInitialized();
199 43 : }
200 :
201 : } // namespace internal
202 : } // namespace v8
|