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 | 6 |
7 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/base/ieee754.h" | 10 #include "src/base/ieee754.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 \ | 103 \ |
104 V8_NOINLINE static Object* Builtin_Impl_Stats_##name( \ | 104 V8_NOINLINE static Object* Builtin_Impl_Stats_##name( \ |
105 int args_length, Object** args_object, Isolate* isolate) { \ | 105 int args_length, Object** args_object, Isolate* isolate) { \ |
106 BuiltinArguments args(args_length, args_object); \ | 106 BuiltinArguments args(args_length, args_object); \ |
107 RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Builtin_##name); \ | 107 RuntimeCallTimerScope timer(isolate, &RuntimeCallStats::Builtin_##name); \ |
108 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \ | 108 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \ |
109 "V8.Builtin_" #name); \ | 109 "V8.Builtin_" #name); \ |
110 return Builtin_Impl_##name(args, isolate); \ | 110 return Builtin_Impl_##name(args, isolate); \ |
111 } \ | 111 } \ |
112 \ | 112 \ |
113 MUST_USE_RESULT static Object* Builtin_##name( \ | 113 MUST_USE_RESULT Object* Builtin_##name( \ |
114 int args_length, Object** args_object, Isolate* isolate) { \ | 114 int args_length, Object** args_object, Isolate* isolate) { \ |
115 DCHECK(isolate->context() == nullptr || isolate->context()->IsContext()); \ | 115 DCHECK(isolate->context() == nullptr || isolate->context()->IsContext()); \ |
116 if (FLAG_runtime_call_stats) { \ | 116 if (FLAG_runtime_call_stats) { \ |
117 return Builtin_Impl_Stats_##name(args_length, args_object, isolate); \ | 117 return Builtin_Impl_Stats_##name(args_length, args_object, isolate); \ |
118 } \ | 118 } \ |
119 BuiltinArguments args(args_length, args_object); \ | 119 BuiltinArguments args(args_length, args_object); \ |
120 return Builtin_Impl_##name(args, isolate); \ | 120 return Builtin_Impl_##name(args, isolate); \ |
121 } \ | 121 } \ |
122 \ | 122 \ |
123 MUST_USE_RESULT static Object* Builtin_Impl_##name(BuiltinArguments args, \ | 123 MUST_USE_RESULT static Object* Builtin_Impl_##name(BuiltinArguments args, \ |
(...skipping 6277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6401 } | 6401 } |
6402 | 6402 |
6403 void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) { | 6403 void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) { |
6404 DebugCodegen::GenerateFrameDropperLiveEdit(masm); | 6404 DebugCodegen::GenerateFrameDropperLiveEdit(masm); |
6405 } | 6405 } |
6406 | 6406 |
6407 } // namespace | 6407 } // namespace |
6408 | 6408 |
6409 Builtins::Builtins() : initialized_(false) { | 6409 Builtins::Builtins() : initialized_(false) { |
6410 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); | 6410 memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); |
6411 memset(names_, 0, sizeof(names_[0]) * builtin_count); | |
6412 } | 6411 } |
6413 | 6412 |
6414 Builtins::~Builtins() {} | 6413 Builtins::~Builtins() {} |
6415 | 6414 |
6416 #define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name), | 6415 namespace { |
6417 Address const Builtins::c_functions_[cfunction_count] = { | 6416 void PostBuildProfileAndTracing(Isolate* isolate, Code* code, |
6418 BUILTIN_LIST_C(DEF_ENUM_C)}; | 6417 const char* name) { |
6419 #undef DEF_ENUM_C | 6418 PROFILE(isolate, CodeCreateEvent(CodeEventListener::BUILTIN_TAG, |
| 6419 AbstractCode::cast(code), name)); |
| 6420 #ifdef ENABLE_DISASSEMBLER |
| 6421 if (FLAG_print_builtin_code) { |
| 6422 CodeTracer::Scope trace_scope(isolate->GetCodeTracer()); |
| 6423 OFStream os(trace_scope.file()); |
| 6424 os << "Builtin: " << name << "\n"; |
| 6425 code->Disassemble(name, os); |
| 6426 os << "\n"; |
| 6427 } |
| 6428 #endif |
| 6429 } |
6420 | 6430 |
6421 struct BuiltinDesc { | 6431 typedef void (*MacroAssemblerGenerator)(MacroAssembler*); |
6422 Handle<Code> (*builder)(Isolate*, struct BuiltinDesc const*); | 6432 typedef void (*CodeAssemblerGenerator)(CodeStubAssembler*); |
6423 byte* generator; | |
6424 byte* c_code; | |
6425 const char* s_name; // name is only used for generating log information. | |
6426 int name; | |
6427 Code::Flags flags; | |
6428 Builtins::ExitFrameType exit_frame_type; | |
6429 int argc; | |
6430 }; | |
6431 | 6433 |
6432 #define BUILTIN_FUNCTION_TABLE_INIT \ | 6434 Code* BuildWithMacroAssembler(Isolate* isolate, |
6433 { \ | 6435 MacroAssemblerGenerator generator, |
6434 V8_ONCE_INIT, {} \ | 6436 Code::Flags flags, const char* s_name) { |
6435 } | 6437 HandleScope scope(isolate); |
6436 | |
6437 class BuiltinFunctionTable { | |
6438 public: | |
6439 BuiltinDesc* functions() { | |
6440 base::CallOnce(&once_, &Builtins::InitBuiltinFunctionTable); | |
6441 return functions_; | |
6442 } | |
6443 | |
6444 base::OnceType once_; | |
6445 BuiltinDesc functions_[Builtins::builtin_count + 1]; | |
6446 | |
6447 friend class Builtins; | |
6448 }; | |
6449 | |
6450 namespace { | |
6451 | |
6452 BuiltinFunctionTable builtin_function_table = BUILTIN_FUNCTION_TABLE_INIT; | |
6453 | |
6454 Handle<Code> MacroAssemblerBuilder(Isolate* isolate, | |
6455 BuiltinDesc const* builtin_desc) { | |
6456 // For now we generate builtin adaptor code into a stack-allocated | |
6457 // buffer, before copying it into individual code objects. Be careful | |
6458 // with alignment, some platforms don't like unaligned code. | |
6459 #ifdef DEBUG | |
6460 // We can generate a lot of debug code on Arm64. | |
6461 const size_t buffer_size = 32 * KB; | 6438 const size_t buffer_size = 32 * KB; |
6462 #elif V8_TARGET_ARCH_PPC64 | 6439 byte buffer[buffer_size]; // NOLINT(runtime/arrays) |
6463 // 8 KB is insufficient on PPC64 when FLAG_debug_code is on. | 6440 MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes); |
6464 const size_t buffer_size = 10 * KB; | |
6465 #else | |
6466 const size_t buffer_size = 8 * KB; | |
6467 #endif | |
6468 union { | |
6469 int force_alignment; | |
6470 byte buffer[buffer_size]; // NOLINT(runtime/arrays) | |
6471 } u; | |
6472 | |
6473 MacroAssembler masm(isolate, u.buffer, sizeof(u.buffer), | |
6474 CodeObjectRequired::kYes); | |
6475 // Generate the code/adaptor. | |
6476 typedef void (*Generator)(MacroAssembler*, int, Builtins::ExitFrameType); | |
6477 Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator); | |
6478 // We pass all arguments to the generator, but it may not use all of | |
6479 // them. This works because the first arguments are on top of the | |
6480 // stack. | |
6481 DCHECK(!masm.has_frame()); | 6441 DCHECK(!masm.has_frame()); |
6482 g(&masm, builtin_desc->name, builtin_desc->exit_frame_type); | 6442 generator(&masm); |
6483 // Move the code into the object heap. | |
6484 CodeDesc desc; | 6443 CodeDesc desc; |
6485 masm.GetCode(&desc); | 6444 masm.GetCode(&desc); |
6486 Code::Flags flags = builtin_desc->flags; | 6445 Handle<Code> code = |
6487 return isolate->factory()->NewCode(desc, flags, masm.CodeObject()); | 6446 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
| 6447 PostBuildProfileAndTracing(isolate, *code, s_name); |
| 6448 return *code; |
| 6449 } |
| 6450 |
| 6451 Code* BuildAdaptor(Isolate* isolate, Address builtin_address, |
| 6452 Builtins::ExitFrameType exit_frame_type, Code::Flags flags, |
| 6453 const char* name) { |
| 6454 HandleScope scope(isolate); |
| 6455 const size_t buffer_size = 32 * KB; |
| 6456 byte buffer[buffer_size]; // NOLINT(runtime/arrays) |
| 6457 MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes); |
| 6458 DCHECK(!masm.has_frame()); |
| 6459 Builtins::Generate_Adaptor(&masm, builtin_address, exit_frame_type); |
| 6460 CodeDesc desc; |
| 6461 masm.GetCode(&desc); |
| 6462 Handle<Code> code = |
| 6463 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
| 6464 PostBuildProfileAndTracing(isolate, *code, name); |
| 6465 return *code; |
6488 } | 6466 } |
6489 | 6467 |
6490 // Builder for builtins implemented in TurboFan with JS linkage. | 6468 // Builder for builtins implemented in TurboFan with JS linkage. |
6491 Handle<Code> CodeStubAssemblerBuilderJS(Isolate* isolate, | 6469 Code* BuildWithCodeStubAssemblerJS(Isolate* isolate, |
6492 BuiltinDesc const* builtin_desc) { | 6470 CodeAssemblerGenerator generator, int argc, |
| 6471 Code::Flags flags, const char* name) { |
| 6472 HandleScope scope(isolate); |
6493 Zone zone(isolate->allocator()); | 6473 Zone zone(isolate->allocator()); |
6494 CodeStubAssembler assembler(isolate, &zone, builtin_desc->argc, | 6474 CodeStubAssembler assembler(isolate, &zone, argc, flags, name); |
6495 builtin_desc->flags, builtin_desc->s_name); | 6475 generator(&assembler); |
6496 // Generate the code/adaptor. | 6476 Handle<Code> code = assembler.GenerateCode(); |
6497 typedef void (*Generator)(CodeStubAssembler*); | 6477 PostBuildProfileAndTracing(isolate, *code, name); |
6498 Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator); | 6478 return *code; |
6499 g(&assembler); | |
6500 return assembler.GenerateCode(); | |
6501 } | 6479 } |
6502 | 6480 |
6503 // Builder for builtins implemented in TurboFan with CallStub linkage. | 6481 // Builder for builtins implemented in TurboFan with CallStub linkage. |
6504 Handle<Code> CodeStubAssemblerBuilderCS(Isolate* isolate, | 6482 Code* BuildWithCodeStubAssemblerCS(Isolate* isolate, |
6505 BuiltinDesc const* builtin_desc) { | 6483 CodeAssemblerGenerator generator, |
| 6484 CallDescriptors::Key interface_descriptor, |
| 6485 Code::Flags flags, const char* name) { |
| 6486 HandleScope scope(isolate); |
6506 Zone zone(isolate->allocator()); | 6487 Zone zone(isolate->allocator()); |
6507 // The interface descriptor with given key must be initialized at this point | 6488 // The interface descriptor with given key must be initialized at this point |
6508 // and this construction just queries the details from the descriptors table. | 6489 // and this construction just queries the details from the descriptors table. |
6509 CallInterfaceDescriptor descriptor( | 6490 CallInterfaceDescriptor descriptor(isolate, interface_descriptor); |
6510 isolate, static_cast<CallDescriptors::Key>(builtin_desc->argc)); | |
6511 // Ensure descriptor is already initialized. | 6491 // Ensure descriptor is already initialized. |
6512 DCHECK_NOT_NULL(descriptor.GetFunctionType()); | 6492 DCHECK_NOT_NULL(descriptor.GetFunctionType()); |
6513 CodeStubAssembler assembler(isolate, &zone, descriptor, builtin_desc->flags, | 6493 CodeStubAssembler assembler(isolate, &zone, descriptor, flags, name); |
6514 builtin_desc->s_name); | 6494 generator(&assembler); |
6515 // Generate the code/adaptor. | 6495 Handle<Code> code = assembler.GenerateCode(); |
6516 typedef void (*Generator)(CodeStubAssembler*); | 6496 PostBuildProfileAndTracing(isolate, *code, name); |
6517 Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator); | 6497 return *code; |
6518 g(&assembler); | |
6519 return assembler.GenerateCode(); | |
6520 } | 6498 } |
6521 | 6499 } // anonymous namespace |
6522 } // namespace | |
6523 | |
6524 // Define array of pointers to generators and C builtin functions. | |
6525 // We do this in a sort of roundabout way so that we can do the initialization | |
6526 // within the lexical scope of Builtins:: and within a context where | |
6527 // Code::Flags names a non-abstract type. | |
6528 void Builtins::InitBuiltinFunctionTable() { | |
6529 BuiltinDesc* functions = builtin_function_table.functions_; | |
6530 functions[builtin_count].builder = nullptr; | |
6531 functions[builtin_count].generator = nullptr; | |
6532 functions[builtin_count].c_code = nullptr; | |
6533 functions[builtin_count].s_name = nullptr; | |
6534 functions[builtin_count].name = builtin_count; | |
6535 functions[builtin_count].flags = static_cast<Code::Flags>(0); | |
6536 functions[builtin_count].exit_frame_type = EXIT; | |
6537 functions[builtin_count].argc = 0; | |
6538 | |
6539 #define DEF_CPP(Name) \ | |
6540 functions->builder = &MacroAssemblerBuilder; \ | |
6541 functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ | |
6542 functions->c_code = FUNCTION_ADDR(Builtin_##Name); \ | |
6543 functions->s_name = #Name; \ | |
6544 functions->name = c_##Name; \ | |
6545 functions->flags = Code::ComputeFlags(Code::BUILTIN); \ | |
6546 functions->exit_frame_type = BUILTIN_EXIT; \ | |
6547 functions->argc = 0; \ | |
6548 ++functions; | |
6549 | |
6550 #define DEF_API(Name) \ | |
6551 functions->builder = &MacroAssemblerBuilder; \ | |
6552 functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ | |
6553 functions->c_code = FUNCTION_ADDR(Builtin_##Name); \ | |
6554 functions->s_name = #Name; \ | |
6555 functions->name = c_##Name; \ | |
6556 functions->flags = Code::ComputeFlags(Code::BUILTIN); \ | |
6557 functions->exit_frame_type = EXIT; \ | |
6558 functions->argc = 0; \ | |
6559 ++functions; | |
6560 | |
6561 #define DEF_TFJ(Name, Argc) \ | |
6562 functions->builder = &CodeStubAssemblerBuilderJS; \ | |
6563 functions->generator = FUNCTION_ADDR(Generate_##Name); \ | |
6564 functions->c_code = NULL; \ | |
6565 functions->s_name = #Name; \ | |
6566 functions->name = k##Name; \ | |
6567 functions->flags = Code::ComputeFlags(Code::BUILTIN); \ | |
6568 functions->exit_frame_type = EXIT; \ | |
6569 functions->argc = Argc; \ | |
6570 ++functions; | |
6571 | |
6572 #define DEF_TFS(Name, Kind, Extra, InterfaceDescriptor) \ | |
6573 functions->builder = &CodeStubAssemblerBuilderCS; \ | |
6574 functions->generator = FUNCTION_ADDR(Generate_##Name); \ | |
6575 functions->c_code = NULL; \ | |
6576 functions->s_name = #Name; \ | |
6577 functions->name = k##Name; \ | |
6578 functions->flags = Code::ComputeFlags(Code::Kind, Extra); \ | |
6579 functions->exit_frame_type = EXIT; \ | |
6580 functions->argc = CallDescriptors::InterfaceDescriptor; \ | |
6581 ++functions; | |
6582 | |
6583 #define DEF_ASM(Name) \ | |
6584 functions->builder = &MacroAssemblerBuilder; \ | |
6585 functions->generator = FUNCTION_ADDR(Generate_##Name); \ | |
6586 functions->c_code = NULL; \ | |
6587 functions->s_name = #Name; \ | |
6588 functions->name = k##Name; \ | |
6589 functions->flags = Code::ComputeFlags(Code::BUILTIN); \ | |
6590 functions->exit_frame_type = EXIT; \ | |
6591 functions->argc = 0; \ | |
6592 ++functions; | |
6593 | |
6594 #define DEF_ASH(Name, Kind, Extra) \ | |
6595 functions->builder = &MacroAssemblerBuilder; \ | |
6596 functions->generator = FUNCTION_ADDR(Generate_##Name); \ | |
6597 functions->c_code = NULL; \ | |
6598 functions->s_name = #Name; \ | |
6599 functions->name = k##Name; \ | |
6600 functions->flags = Code::ComputeFlags(Code::Kind, Extra); \ | |
6601 functions->exit_frame_type = EXIT; \ | |
6602 functions->argc = 0; \ | |
6603 ++functions; | |
6604 | |
6605 BUILTIN_LIST(DEF_CPP, DEF_API, DEF_TFJ, DEF_TFS, DEF_ASM, DEF_ASH, DEF_ASM) | |
6606 | |
6607 #undef DEF_CPP | |
6608 #undef DEF_API | |
6609 #undef DEF_TFJ | |
6610 #undef DEF_TFS | |
6611 #undef DEF_ASM | |
6612 #undef DEF_ASH | |
6613 } | |
6614 | 6500 |
6615 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { | 6501 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { |
6616 DCHECK(!initialized_); | 6502 DCHECK(!initialized_); |
6617 | 6503 |
6618 // Create a scope for the handles in the builtins. | 6504 // Create a scope for the handles in the builtins. |
6619 HandleScope scope(isolate); | 6505 HandleScope scope(isolate); |
6620 | 6506 |
6621 #define INITIALIZE_CALL_DESCRIPTOR(name, kind, extra, interface_descriptor) \ | 6507 if (create_heap_objects) { |
6622 { interface_descriptor##Descriptor descriptor(isolate); } | 6508 int index = 0; |
6623 BUILTIN_LIST_TFS(INITIALIZE_CALL_DESCRIPTOR) | 6509 const Code::Flags kBuiltinFlags = Code::ComputeFlags(Code::BUILTIN); |
6624 #undef INITIALIZE_CALL_DESCRIPTOR | 6510 Code* code; |
| 6511 #define BUILD_CPP(Name) \ |
| 6512 code = BuildAdaptor(isolate, FUNCTION_ADDR(Builtin_##Name), BUILTIN_EXIT, \ |
| 6513 kBuiltinFlags, #Name); \ |
| 6514 builtins_[index++] = code; |
| 6515 #define BUILD_API(Name) \ |
| 6516 code = BuildAdaptor(isolate, FUNCTION_ADDR(Builtin_##Name), EXIT, \ |
| 6517 kBuiltinFlags, #Name); \ |
| 6518 builtins_[index++] = code; |
| 6519 #define BUILD_TFJ(Name, Argc) \ |
| 6520 code = BuildWithCodeStubAssemblerJS(isolate, &Generate_##Name, Argc, \ |
| 6521 kBuiltinFlags, #Name); \ |
| 6522 builtins_[index++] = code; |
| 6523 #define BUILD_TFS(Name, Kind, Extra, InterfaceDescriptor) \ |
| 6524 { InterfaceDescriptor##Descriptor descriptor(isolate); } \ |
| 6525 code = BuildWithCodeStubAssemblerCS( \ |
| 6526 isolate, &Generate_##Name, CallDescriptors::InterfaceDescriptor, \ |
| 6527 Code::ComputeFlags(Code::Kind, Extra), #Name); \ |
| 6528 builtins_[index++] = code; |
| 6529 #define BUILD_ASM(Name) \ |
| 6530 code = \ |
| 6531 BuildWithMacroAssembler(isolate, Generate_##Name, kBuiltinFlags, #Name); \ |
| 6532 builtins_[index++] = code; |
| 6533 #define BUILD_ASH(Name, Kind, Extra) \ |
| 6534 code = BuildWithMacroAssembler( \ |
| 6535 isolate, Generate_##Name, Code::ComputeFlags(Code::Kind, Extra), #Name); \ |
| 6536 builtins_[index++] = code; |
6625 | 6537 |
6626 const BuiltinDesc* functions = builtin_function_table.functions(); | 6538 BUILTIN_LIST(BUILD_CPP, BUILD_API, BUILD_TFJ, BUILD_TFS, BUILD_ASM, |
| 6539 BUILD_ASH, BUILD_ASM); |
6627 | 6540 |
6628 // Traverse the list of builtins and generate an adaptor in a | 6541 #undef BUILD_CPP |
6629 // separate code object for each one. | 6542 #undef BUILD_API |
6630 for (int i = 0; i < builtin_count; i++) { | 6543 #undef BUILD_TFJ |
6631 if (create_heap_objects) { | 6544 #undef BUILD_TFS |
6632 Handle<Code> code = (*functions[i].builder)(isolate, functions + i); | 6545 #undef BUILD_ASM |
6633 // Log the event and add the code to the builtins array. | 6546 #undef BUILD_ASH |
6634 PROFILE(isolate, | 6547 CHECK_EQ(builtin_count, index); |
6635 CodeCreateEvent(CodeEventListener::BUILTIN_TAG, | 6548 for (int i = 0; i < builtin_count; i++) { |
6636 AbstractCode::cast(*code), functions[i].s_name)); | 6549 Code::cast(builtins_[i])->set_builtin_index(i); |
6637 builtins_[i] = *code; | |
6638 code->set_builtin_index(i); | |
6639 #ifdef ENABLE_DISASSEMBLER | |
6640 if (FLAG_print_builtin_code) { | |
6641 CodeTracer::Scope trace_scope(isolate->GetCodeTracer()); | |
6642 OFStream os(trace_scope.file()); | |
6643 os << "Builtin: " << functions[i].s_name << "\n"; | |
6644 code->Disassemble(functions[i].s_name, os); | |
6645 os << "\n"; | |
6646 } | |
6647 #endif | |
6648 } else { | |
6649 // Deserializing. The values will be filled in during IterateBuiltins. | |
6650 builtins_[i] = NULL; | |
6651 } | 6550 } |
6652 names_[i] = functions[i].s_name; | |
6653 } | 6551 } |
6654 | 6552 |
6655 // Mark as initialized. | 6553 // Mark as initialized. |
6656 initialized_ = true; | 6554 initialized_ = true; |
6657 } | 6555 } |
6658 | 6556 |
6659 void Builtins::TearDown() { initialized_ = false; } | 6557 void Builtins::TearDown() { initialized_ = false; } |
6660 | 6558 |
6661 void Builtins::IterateBuiltins(ObjectVisitor* v) { | 6559 void Builtins::IterateBuiltins(ObjectVisitor* v) { |
6662 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); | 6560 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); |
6663 } | 6561 } |
6664 | 6562 |
6665 const char* Builtins::Lookup(byte* pc) { | 6563 const char* Builtins::Lookup(byte* pc) { |
6666 // may be called during initialization (disassembler!) | 6564 // may be called during initialization (disassembler!) |
6667 if (initialized_) { | 6565 if (initialized_) { |
6668 for (int i = 0; i < builtin_count; i++) { | 6566 for (int i = 0; i < builtin_count; i++) { |
6669 Code* entry = Code::cast(builtins_[i]); | 6567 Code* entry = Code::cast(builtins_[i]); |
6670 if (entry->contains(pc)) { | 6568 if (entry->contains(pc)) return name(i); |
6671 return names_[i]; | |
6672 } | |
6673 } | 6569 } |
6674 } | 6570 } |
6675 return NULL; | 6571 return NULL; |
6676 } | 6572 } |
6677 | 6573 |
| 6574 const char* Builtins::name(int index) { |
| 6575 switch (index) { |
| 6576 #define CASE(Name, ...) \ |
| 6577 case k##Name: \ |
| 6578 return #Name; |
| 6579 BUILTIN_LIST_ALL(CASE) |
| 6580 #undef CASE |
| 6581 default: |
| 6582 UNREACHABLE(); |
| 6583 break; |
| 6584 } |
| 6585 return ""; |
| 6586 } |
| 6587 |
6678 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) { | 6588 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) { |
6679 masm->TailCallRuntime(Runtime::kInterrupt); | 6589 masm->TailCallRuntime(Runtime::kInterrupt); |
6680 } | 6590 } |
6681 | 6591 |
6682 void Builtins::Generate_StackCheck(MacroAssembler* masm) { | 6592 void Builtins::Generate_StackCheck(MacroAssembler* masm) { |
6683 masm->TailCallRuntime(Runtime::kStackGuard); | 6593 masm->TailCallRuntime(Runtime::kStackGuard); |
6684 } | 6594 } |
6685 | 6595 |
6686 namespace { | 6596 namespace { |
6687 | 6597 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6923 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ | 6833 #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \ |
6924 Handle<Code> Builtins::Name() { \ | 6834 Handle<Code> Builtins::Name() { \ |
6925 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ | 6835 Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \ |
6926 return Handle<Code>(code_address); \ | 6836 return Handle<Code>(code_address); \ |
6927 } | 6837 } |
6928 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) | 6838 BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR) |
6929 #undef DEFINE_BUILTIN_ACCESSOR | 6839 #undef DEFINE_BUILTIN_ACCESSOR |
6930 | 6840 |
6931 } // namespace internal | 6841 } // namespace internal |
6932 } // namespace v8 | 6842 } // namespace v8 |
OLD | NEW |