OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/api.h" | 6 #include "src/api.h" |
7 #include "src/assembler-inl.h" | 7 #include "src/assembler-inl.h" |
8 #include "src/builtins/builtins-descriptors.h" | 8 #include "src/builtins/builtins-descriptors.h" |
9 #include "src/callable.h" | 9 #include "src/callable.h" |
| 10 #include "src/code-events.h" |
| 11 #include "src/compiler/code-assembler.h" |
| 12 #include "src/ic/ic-state.h" |
| 13 #include "src/interface-descriptors.h" |
10 #include "src/isolate.h" | 14 #include "src/isolate.h" |
11 #include "src/macro-assembler.h" | 15 #include "src/macro-assembler.h" |
12 #include "src/objects-inl.h" | 16 #include "src/objects-inl.h" |
13 | 17 |
14 namespace v8 { | 18 namespace v8 { |
15 namespace internal { | 19 namespace internal { |
16 | 20 |
17 // Forward declarations for C++ builtins. | 21 // Forward declarations for C++ builtins. |
18 #define FORWARD_DECLARE(Name) \ | 22 #define FORWARD_DECLARE(Name) \ |
19 Object* Builtin_##Name(int argc, Object** args, Isolate* isolate); | 23 Object* Builtin_##Name(int argc, Object** args, Isolate* isolate); |
20 BUILTIN_LIST_C(FORWARD_DECLARE) | 24 BUILTIN_LIST_C(FORWARD_DECLARE) |
21 | 25 |
22 Builtins::Builtins() : initialized_(false) { | 26 Builtins::Builtins() : initialized_(false) { |
23 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); | 27 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); |
24 } | 28 } |
25 | 29 |
26 Builtins::~Builtins() {} | 30 Builtins::~Builtins() {} |
27 | 31 |
| 32 namespace { |
| 33 void PostBuildProfileAndTracing(Isolate* isolate, Code* code, |
| 34 const char* name) { |
| 35 PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG, |
| 36 AbstractCode::cast(code), name)); |
| 37 #ifdef ENABLE_DISASSEMBLER |
| 38 if (FLAG_print_builtin_code) { |
| 39 CodeTracer::Scope trace_scope(isolate->GetCodeTracer()); |
| 40 OFStream os(trace_scope.file()); |
| 41 os << "Builtin: " << name << "\n"; |
| 42 code->Disassemble(name, os); |
| 43 os << "\n"; |
| 44 } |
| 45 #endif |
| 46 } |
| 47 |
| 48 typedef void (*MacroAssemblerGenerator)(MacroAssembler*); |
| 49 typedef void (*CodeAssemblerGenerator)(compiler::CodeAssemblerState*); |
| 50 |
| 51 Code* BuildWithMacroAssembler(Isolate* isolate, |
| 52 MacroAssemblerGenerator generator, |
| 53 Code::Flags flags, const char* s_name) { |
| 54 HandleScope scope(isolate); |
| 55 const size_t buffer_size = 32 * KB; |
| 56 byte buffer[buffer_size]; // NOLINT(runtime/arrays) |
| 57 MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes); |
| 58 DCHECK(!masm.has_frame()); |
| 59 generator(&masm); |
| 60 CodeDesc desc; |
| 61 masm.GetCode(&desc); |
| 62 Handle<Code> code = |
| 63 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
| 64 PostBuildProfileAndTracing(isolate, *code, s_name); |
| 65 return *code; |
| 66 } |
| 67 |
| 68 Code* BuildAdaptor(Isolate* isolate, Address builtin_address, |
| 69 Builtins::ExitFrameType exit_frame_type, Code::Flags flags, |
| 70 const char* name) { |
| 71 HandleScope scope(isolate); |
| 72 const size_t buffer_size = 32 * KB; |
| 73 byte buffer[buffer_size]; // NOLINT(runtime/arrays) |
| 74 MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes); |
| 75 DCHECK(!masm.has_frame()); |
| 76 Builtins::Generate_Adaptor(&masm, builtin_address, exit_frame_type); |
| 77 CodeDesc desc; |
| 78 masm.GetCode(&desc); |
| 79 Handle<Code> code = |
| 80 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
| 81 PostBuildProfileAndTracing(isolate, *code, name); |
| 82 return *code; |
| 83 } |
| 84 |
| 85 // Builder for builtins implemented in TurboFan with JS linkage. |
| 86 Code* BuildWithCodeStubAssemblerJS(Isolate* isolate, |
| 87 CodeAssemblerGenerator generator, int argc, |
| 88 Code::Flags flags, const char* name) { |
| 89 HandleScope scope(isolate); |
| 90 Zone zone(isolate->allocator(), ZONE_NAME); |
| 91 const int argc_with_recv = |
| 92 (argc == SharedFunctionInfo::kDontAdaptArgumentsSentinel) ? 0 : argc + 1; |
| 93 compiler::CodeAssemblerState state(isolate, &zone, argc_with_recv, flags, |
| 94 name); |
| 95 generator(&state); |
| 96 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state); |
| 97 PostBuildProfileAndTracing(isolate, *code, name); |
| 98 return *code; |
| 99 } |
| 100 |
| 101 // Builder for builtins implemented in TurboFan with CallStub linkage. |
| 102 Code* BuildWithCodeStubAssemblerCS(Isolate* isolate, |
| 103 CodeAssemblerGenerator generator, |
| 104 CallDescriptors::Key interface_descriptor, |
| 105 Code::Flags flags, const char* name, |
| 106 int result_size) { |
| 107 HandleScope scope(isolate); |
| 108 Zone zone(isolate->allocator(), ZONE_NAME); |
| 109 // The interface descriptor with given key must be initialized at this point |
| 110 // and this construction just queries the details from the descriptors table. |
| 111 CallInterfaceDescriptor descriptor(isolate, interface_descriptor); |
| 112 // Ensure descriptor is already initialized. |
| 113 DCHECK_LE(0, descriptor.GetRegisterParameterCount()); |
| 114 compiler::CodeAssemblerState state(isolate, &zone, descriptor, flags, name, |
| 115 result_size); |
| 116 generator(&state); |
| 117 Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state); |
| 118 PostBuildProfileAndTracing(isolate, *code, name); |
| 119 return *code; |
| 120 } |
| 121 } // anonymous namespace |
| 122 |
| 123 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { |
| 124 DCHECK(!initialized_); |
| 125 |
| 126 // Create a scope for the handles in the builtins. |
| 127 HandleScope scope(isolate); |
| 128 |
| 129 if (create_heap_objects) { |
| 130 int index = 0; |
| 131 const Code::Flags kBuiltinFlags = Code::ComputeFlags(Code::BUILTIN); |
| 132 Code* code; |
| 133 #define BUILD_CPP(Name) \ |
| 134 code = BuildAdaptor(isolate, FUNCTION_ADDR(Builtin_##Name), BUILTIN_EXIT, \ |
| 135 kBuiltinFlags, #Name); \ |
| 136 builtins_[index++] = code; |
| 137 #define BUILD_API(Name) \ |
| 138 code = BuildAdaptor(isolate, FUNCTION_ADDR(Builtin_##Name), EXIT, \ |
| 139 kBuiltinFlags, #Name); \ |
| 140 builtins_[index++] = code; |
| 141 #define BUILD_TFJ(Name, Argc, ...) \ |
| 142 code = BuildWithCodeStubAssemblerJS(isolate, &Generate_##Name, Argc, \ |
| 143 kBuiltinFlags, #Name); \ |
| 144 builtins_[index++] = code; |
| 145 #define BUILD_TFS(Name, InterfaceDescriptor, result_size) \ |
| 146 { InterfaceDescriptor##Descriptor descriptor(isolate); } \ |
| 147 code = BuildWithCodeStubAssemblerCS(isolate, &Generate_##Name, \ |
| 148 CallDescriptors::InterfaceDescriptor, \ |
| 149 kBuiltinFlags, #Name, result_size); \ |
| 150 builtins_[index++] = code; |
| 151 #define BUILD_TFH(Name, Kind, Extra, InterfaceDescriptor) \ |
| 152 { InterfaceDescriptor##Descriptor descriptor(isolate); } \ |
| 153 /* Return size for IC builtins/handlers is always 1. */ \ |
| 154 code = BuildWithCodeStubAssemblerCS( \ |
| 155 isolate, &Generate_##Name, CallDescriptors::InterfaceDescriptor, \ |
| 156 Code::ComputeFlags(Code::Kind, Extra), #Name, 1); \ |
| 157 builtins_[index++] = code; |
| 158 #define BUILD_ASM(Name) \ |
| 159 code = \ |
| 160 BuildWithMacroAssembler(isolate, Generate_##Name, kBuiltinFlags, #Name); \ |
| 161 builtins_[index++] = code; |
| 162 |
| 163 BUILTIN_LIST(BUILD_CPP, BUILD_API, BUILD_TFJ, BUILD_TFS, BUILD_TFH, |
| 164 BUILD_ASM, BUILD_ASM); |
| 165 |
| 166 #undef BUILD_CPP |
| 167 #undef BUILD_API |
| 168 #undef BUILD_TFJ |
| 169 #undef BUILD_TFS |
| 170 #undef BUILD_TFH |
| 171 #undef BUILD_ASM |
| 172 CHECK_EQ(builtin_count, index); |
| 173 for (int i = 0; i < builtin_count; i++) { |
| 174 Code::cast(builtins_[i])->set_builtin_index(i); |
| 175 } |
| 176 |
| 177 #define SET_PROMISE_REJECTION_PREDICTION(Name) \ |
| 178 Code::cast(builtins_[k##Name])->set_is_promise_rejection(true); |
| 179 |
| 180 BUILTIN_PROMISE_REJECTION_PREDICTION_LIST(SET_PROMISE_REJECTION_PREDICTION) |
| 181 #undef SET_PROMISE_REJECTION_PREDICTION |
| 182 |
| 183 #define SET_EXCEPTION_CAUGHT_PREDICTION(Name) \ |
| 184 Code::cast(builtins_[k##Name])->set_is_exception_caught(true); |
| 185 |
| 186 BUILTIN_EXCEPTION_CAUGHT_PREDICTION_LIST(SET_EXCEPTION_CAUGHT_PREDICTION) |
| 187 #undef SET_EXCEPTION_CAUGHT_PREDICTION |
| 188 |
| 189 #define SET_CODE_NON_TAGGED_PARAMS(Name) \ |
| 190 Code::cast(builtins_[k##Name])->set_has_tagged_params(false); |
| 191 BUILTINS_WITH_UNTAGGED_PARAMS(SET_CODE_NON_TAGGED_PARAMS) |
| 192 #undef SET_CODE_NON_TAGGED_PARAMS |
| 193 } |
| 194 |
| 195 // Mark as initialized. |
| 196 initialized_ = true; |
| 197 } |
| 198 |
28 void Builtins::TearDown() { initialized_ = false; } | 199 void Builtins::TearDown() { initialized_ = false; } |
29 | 200 |
30 void Builtins::IterateBuiltins(ObjectVisitor* v) { | 201 void Builtins::IterateBuiltins(ObjectVisitor* v) { |
31 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); | 202 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); |
32 } | 203 } |
33 | 204 |
34 const char* Builtins::Lookup(byte* pc) { | 205 const char* Builtins::Lookup(byte* pc) { |
35 // may be called during initialization (disassembler!) | 206 // may be called during initialization (disassembler!) |
36 if (initialized_) { | 207 if (initialized_) { |
37 for (int i = 0; i < builtin_count; i++) { | 208 for (int i = 0; i < builtin_count; i++) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 // TODO(jochen): Remove this. | 404 // TODO(jochen): Remove this. |
234 if (responsible_context.is_null()) { | 405 if (responsible_context.is_null()) { |
235 return true; | 406 return true; |
236 } | 407 } |
237 if (*responsible_context == target->context()) return true; | 408 if (*responsible_context == target->context()) return true; |
238 return isolate->MayAccess(responsible_context, target_global_proxy); | 409 return isolate->MayAccess(responsible_context, target_global_proxy); |
239 } | 410 } |
240 | 411 |
241 } // namespace internal | 412 } // namespace internal |
242 } // namespace v8 | 413 } // namespace v8 |
OLD | NEW |