| 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" | |
| 14 #include "src/isolate.h" | 10 #include "src/isolate.h" |
| 15 #include "src/macro-assembler.h" | 11 #include "src/macro-assembler.h" |
| 16 #include "src/objects-inl.h" | 12 #include "src/objects-inl.h" |
| 17 | 13 |
| 18 namespace v8 { | 14 namespace v8 { |
| 19 namespace internal { | 15 namespace internal { |
| 20 | 16 |
| 21 // Forward declarations for C++ builtins. | 17 // Forward declarations for C++ builtins. |
| 22 #define FORWARD_DECLARE(Name) \ | 18 #define FORWARD_DECLARE(Name) \ |
| 23 Object* Builtin_##Name(int argc, Object** args, Isolate* isolate); | 19 Object* Builtin_##Name(int argc, Object** args, Isolate* isolate); |
| 24 BUILTIN_LIST_C(FORWARD_DECLARE) | 20 BUILTIN_LIST_C(FORWARD_DECLARE) |
| 25 | 21 |
| 26 Builtins::Builtins() : initialized_(false) { | 22 Builtins::Builtins() : initialized_(false) { |
| 27 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); | 23 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); |
| 28 } | 24 } |
| 29 | 25 |
| 30 Builtins::~Builtins() {} | 26 Builtins::~Builtins() {} |
| 31 | 27 |
| 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 | |
| 199 void Builtins::TearDown() { initialized_ = false; } | 28 void Builtins::TearDown() { initialized_ = false; } |
| 200 | 29 |
| 201 void Builtins::IterateBuiltins(ObjectVisitor* v) { | 30 void Builtins::IterateBuiltins(ObjectVisitor* v) { |
| 202 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); | 31 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); |
| 203 } | 32 } |
| 204 | 33 |
| 205 const char* Builtins::Lookup(byte* pc) { | 34 const char* Builtins::Lookup(byte* pc) { |
| 206 // may be called during initialization (disassembler!) | 35 // may be called during initialization (disassembler!) |
| 207 if (initialized_) { | 36 if (initialized_) { |
| 208 for (int i = 0; i < builtin_count; i++) { | 37 for (int i = 0; i < builtin_count; i++) { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 // TODO(jochen): Remove this. | 233 // TODO(jochen): Remove this. |
| 405 if (responsible_context.is_null()) { | 234 if (responsible_context.is_null()) { |
| 406 return true; | 235 return true; |
| 407 } | 236 } |
| 408 if (*responsible_context == target->context()) return true; | 237 if (*responsible_context == target->context()) return true; |
| 409 return isolate->MayAccess(responsible_context, target_global_proxy); | 238 return isolate->MayAccess(responsible_context, target_global_proxy); |
| 410 } | 239 } |
| 411 | 240 |
| 412 } // namespace internal | 241 } // namespace internal |
| 413 } // namespace v8 | 242 } // namespace v8 |
| OLD | NEW |