5 #include "src/setup-isolate.h" 7 #include "src/assembler-inl.h" 8 #include "src/builtins/builtins.h" 9 #include "src/code-events.h" 10 #include "src/compiler/code-assembler.h" 11 #include "src/handles-inl.h" 12 #include "src/interface-descriptors.h" 13 #include "src/interpreter/bytecodes.h" 14 #include "src/interpreter/interpreter-generator.h" 15 #include "src/interpreter/interpreter.h" 16 #include "src/isolate.h" 17 #include "src/macro-assembler.h" 18 #include "src/objects-inl.h" 19 #include "src/objects/shared-function-info.h" 20 #include "src/objects/smi.h" 26 #define FORWARD_DECLARE(Name) \ 27 Object* Builtin_##Name(int argc, Address* args, Isolate* isolate); 28 BUILTIN_LIST_C(FORWARD_DECLARE)
29 #undef FORWARD_DECLARE 33 void PostBuildProfileAndTracing(Isolate* isolate, Code code,
const char* name) {
34 PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG,
35 AbstractCode::cast(code), name));
38 AssemblerOptions BuiltinAssemblerOptions(Isolate* isolate,
39 int32_t builtin_index) {
40 AssemblerOptions options = AssemblerOptions::Default(isolate);
41 CHECK(!options.isolate_independent_code);
42 CHECK(!options.use_pc_relative_calls_and_jumps);
44 if (!isolate->ShouldLoadConstantsFromRootList() ||
45 !Builtins::IsIsolateIndependent(builtin_index)) {
49 const base::AddressRegion& code_range =
50 isolate->heap()->memory_allocator()->code_range();
51 bool pc_relative_calls_fit_in_code_range =
52 !code_range.is_empty() &&
53 code_range.size() <= kMaxPCRelativeCodeRangeInMB * MB;
55 options.isolate_independent_code =
true;
56 options.use_pc_relative_calls_and_jumps = pc_relative_calls_fit_in_code_range;
61 typedef void (*MacroAssemblerGenerator)(MacroAssembler*);
62 typedef void (*CodeAssemblerGenerator)(compiler::CodeAssemblerState*);
64 Handle<Code> BuildPlaceholder(Isolate* isolate, int32_t builtin_index) {
65 HandleScope scope(isolate);
66 const size_t buffer_size = 1 * KB;
67 byte buffer[buffer_size];
68 MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes);
69 DCHECK(!masm.has_frame());
71 FrameScope scope(&masm, StackFrame::NONE);
74 masm.Move(kJavaScriptCallCodeStartRegister, Smi::zero());
75 masm.Call(kJavaScriptCallCodeStartRegister);
78 masm.GetCode(isolate, &desc);
79 Handle<Code> code = isolate->factory()->NewCode(
80 desc, Code::BUILTIN, masm.CodeObject(), builtin_index);
81 return scope.CloseAndEscape(code);
84 Code BuildWithMacroAssembler(Isolate* isolate, int32_t builtin_index,
85 MacroAssemblerGenerator generator,
87 HandleScope scope(isolate);
90 CanonicalHandleScope canonical(isolate);
91 const size_t buffer_size = 32 * KB;
92 byte buffer[buffer_size];
94 MacroAssembler masm(isolate, BuiltinAssemblerOptions(isolate, builtin_index),
95 buffer, buffer_size, CodeObjectRequired::kYes);
96 masm.set_builtin_index(builtin_index);
97 DCHECK(!masm.has_frame());
100 masm.GetCode(isolate, &desc);
101 Handle<Code> code = isolate->factory()->NewCode(
102 desc, Code::BUILTIN, masm.CodeObject(), builtin_index);
103 PostBuildProfileAndTracing(isolate, *code, s_name);
107 Code BuildAdaptor(Isolate* isolate, int32_t builtin_index,
108 Address builtin_address,
109 Builtins::ExitFrameType exit_frame_type,
const char* name) {
110 HandleScope scope(isolate);
113 CanonicalHandleScope canonical(isolate);
114 const size_t buffer_size = 32 * KB;
115 byte buffer[buffer_size];
116 MacroAssembler masm(isolate, BuiltinAssemblerOptions(isolate, builtin_index),
117 buffer, buffer_size, CodeObjectRequired::kYes);
118 masm.set_builtin_index(builtin_index);
119 DCHECK(!masm.has_frame());
120 Builtins::Generate_Adaptor(&masm, builtin_address, exit_frame_type);
122 masm.GetCode(isolate, &desc);
123 Handle<Code> code = isolate->factory()->NewCode(
124 desc, Code::BUILTIN, masm.CodeObject(), builtin_index);
125 PostBuildProfileAndTracing(isolate, *code, name);
130 Code BuildWithCodeStubAssemblerJS(Isolate* isolate, int32_t builtin_index,
131 CodeAssemblerGenerator generator,
int argc,
133 HandleScope scope(isolate);
136 CanonicalHandleScope canonical(isolate);
138 SegmentSize segment_size = isolate->serializer_enabled()
139 ? SegmentSize::kLarge
140 : SegmentSize::kDefault;
141 Zone zone(isolate->allocator(), ZONE_NAME, segment_size);
142 const int argc_with_recv =
143 (argc == SharedFunctionInfo::kDontAdaptArgumentsSentinel) ? 0 : argc + 1;
144 compiler::CodeAssemblerState state(
145 isolate, &zone, argc_with_recv, Code::BUILTIN, name,
146 PoisoningMitigationLevel::kDontPoison, builtin_index);
148 Handle<Code> code = compiler::CodeAssembler::GenerateCode(
149 &state, BuiltinAssemblerOptions(isolate, builtin_index));
150 PostBuildProfileAndTracing(isolate, *code, name);
155 Code BuildWithCodeStubAssemblerCS(Isolate* isolate, int32_t builtin_index,
156 CodeAssemblerGenerator generator,
157 CallDescriptors::Key interface_descriptor,
158 const char* name,
int result_size) {
159 HandleScope scope(isolate);
162 CanonicalHandleScope canonical(isolate);
163 SegmentSize segment_size = isolate->serializer_enabled()
164 ? SegmentSize::kLarge
165 : SegmentSize::kDefault;
166 Zone zone(isolate->allocator(), ZONE_NAME, segment_size);
169 CallInterfaceDescriptor descriptor(interface_descriptor);
171 DCHECK_EQ(result_size, descriptor.GetReturnCount());
172 DCHECK_LE(0, descriptor.GetRegisterParameterCount());
173 compiler::CodeAssemblerState state(
174 isolate, &zone, descriptor, Code::BUILTIN, name,
175 PoisoningMitigationLevel::kDontPoison, 0, builtin_index);
177 Handle<Code> code = compiler::CodeAssembler::GenerateCode(
178 &state, BuiltinAssemblerOptions(isolate, builtin_index));
179 PostBuildProfileAndTracing(isolate, *code, name);
186 void SetupIsolateDelegate::AddBuiltin(Builtins* builtins,
int index,
188 DCHECK_EQ(index, code->builtin_index());
189 builtins->set_builtin(index, code);
193 void SetupIsolateDelegate::PopulateWithPlaceholders(Isolate* isolate) {
197 Builtins* builtins = isolate->builtins();
198 HandleScope scope(isolate);
199 for (
int i = 0;
i < Builtins::builtin_count;
i++) {
200 Handle<Code> placeholder = BuildPlaceholder(isolate,
i);
201 AddBuiltin(builtins,
i, *placeholder);
206 void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) {
208 Builtins* builtins = isolate->builtins();
209 DisallowHeapAllocation no_gc;
210 CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
211 static const int kRelocMask =
212 RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
213 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
214 RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET);
215 HeapIterator iterator(isolate->heap());
216 while (HeapObject* obj = iterator.next()) {
217 if (!obj->IsCode())
continue;
218 Code code = Code::cast(obj);
219 bool flush_icache =
false;
220 for (RelocIterator it(code, kRelocMask); !it.done(); it.next()) {
221 RelocInfo* rinfo = it.rinfo();
222 if (RelocInfo::IsCodeTargetMode(rinfo->rmode())) {
223 Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
224 DCHECK_IMPLIES(RelocInfo::IsRelativeCodeTarget(rinfo->rmode()),
225 Builtins::IsIsolateIndependent(target->builtin_index()));
226 if (!target->is_builtin())
continue;
227 Code new_target = builtins->builtin(target->builtin_index());
228 rinfo->set_target_address(new_target->raw_instruction_start(),
229 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
231 DCHECK(RelocInfo::IsEmbeddedObject(rinfo->rmode()));
232 Object*
object = rinfo->target_object();
233 if (!object->IsCode())
continue;
234 Code target = Code::cast(
object);
235 if (!target->is_builtin())
continue;
236 Code new_target = builtins->builtin(target->builtin_index());
237 rinfo->set_target_object(isolate->heap(), new_target,
238 UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
243 Assembler::FlushICache(code->raw_instruction_start(),
244 code->raw_instruction_size());
251 Code GenerateBytecodeHandler(Isolate* isolate,
int builtin_index,
253 interpreter::OperandScale operand_scale,
254 interpreter::Bytecode bytecode) {
255 DCHECK(interpreter::Bytecodes::BytecodeHasHandler(bytecode, operand_scale));
257 Handle<Code> code = interpreter::GenerateBytecodeHandler(
258 isolate, bytecode, operand_scale, builtin_index,
259 BuiltinAssemblerOptions(isolate, builtin_index));
261 PostBuildProfileAndTracing(isolate, *code, name);
269 void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
270 Builtins* builtins = isolate->builtins();
271 DCHECK(!builtins->initialized_);
273 PopulateWithPlaceholders(isolate);
276 HandleScope scope(isolate);
280 #define BUILD_CPP(Name) \ 281 code = BuildAdaptor(isolate, index, FUNCTION_ADDR(Builtin_##Name), \ 282 Builtins::BUILTIN_EXIT, #Name); \ 283 AddBuiltin(builtins, index++, code); 284 #define BUILD_API(Name) \ 285 code = BuildAdaptor(isolate, index, FUNCTION_ADDR(Builtin_##Name), \ 286 Builtins::EXIT, #Name); \ 287 AddBuiltin(builtins, index++, code); 288 #define BUILD_TFJ(Name, Argc, ...) \ 289 code = BuildWithCodeStubAssemblerJS( \ 290 isolate, index, &Builtins::Generate_##Name, Argc, #Name); \ 291 AddBuiltin(builtins, index++, code); 292 #define BUILD_TFC(Name, InterfaceDescriptor, result_size) \ 293 code = BuildWithCodeStubAssemblerCS( \ 294 isolate, index, &Builtins::Generate_##Name, \ 295 CallDescriptors::InterfaceDescriptor, #Name, result_size); \ 296 AddBuiltin(builtins, index++, code); 297 #define BUILD_TFS(Name, ...) \ 300 BuildWithCodeStubAssemblerCS(isolate, index, &Builtins::Generate_##Name, \ 301 CallDescriptors::Name, #Name, 1); \ 302 AddBuiltin(builtins, index++, code); 303 #define BUILD_TFH(Name, InterfaceDescriptor) \ 305 code = BuildWithCodeStubAssemblerCS( \ 306 isolate, index, &Builtins::Generate_##Name, \ 307 CallDescriptors::InterfaceDescriptor, #Name, 1); \ 308 AddBuiltin(builtins, index++, code); 310 #define BUILD_BCH(Name, OperandScale, Bytecode) \ 311 code = GenerateBytecodeHandler(isolate, index, Builtins::name(index), \ 312 OperandScale, Bytecode); \ 313 AddBuiltin(builtins, index++, code); 315 #define BUILD_ASM(Name) \ 316 code = BuildWithMacroAssembler(isolate, index, Builtins::Generate_##Name, \ 318 AddBuiltin(builtins, index++, code); 320 BUILTIN_LIST(BUILD_CPP, BUILD_API, BUILD_TFJ, BUILD_TFC, BUILD_TFS, BUILD_TFH,
321 BUILD_BCH, BUILD_ASM);
331 CHECK_EQ(Builtins::builtin_count, index);
333 ReplacePlaceholders(isolate);
335 #define SET_PROMISE_REJECTION_PREDICTION(Name) \ 336 builtins->builtin(Builtins::k##Name)->set_is_promise_rejection(true); 338 BUILTIN_PROMISE_REJECTION_PREDICTION_LIST(SET_PROMISE_REJECTION_PREDICTION)
339 #undef SET_PROMISE_REJECTION_PREDICTION 341 #define SET_EXCEPTION_CAUGHT_PREDICTION(Name) \ 342 builtins->builtin(Builtins::k##Name)->set_is_exception_caught(true); 344 BUILTIN_EXCEPTION_CAUGHT_PREDICTION_LIST(SET_EXCEPTION_CAUGHT_PREDICTION)
345 #undef SET_EXCEPTION_CAUGHT_PREDICTION 347 builtins->MarkInitialized();