| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 } | 129 } |
| 130 BUILTIN_END | 130 BUILTIN_END |
| 131 | 131 |
| 132 | 132 |
| 133 BUILTIN(EmptyFunction) { | 133 BUILTIN(EmptyFunction) { |
| 134 } | 134 } |
| 135 BUILTIN_END | 135 BUILTIN_END |
| 136 | 136 |
| 137 | 137 |
| 138 BUILTIN(ArrayCodeGeneric) { | 138 BUILTIN(ArrayCodeGeneric) { |
| 139 Counters::array_function_runtime.Increment(); | 139 INC_COUNTER(array_function_runtime); |
| 140 | 140 |
| 141 JSArray* array; | 141 JSArray* array; |
| 142 if (CalledAsConstructor()) { | 142 if (CalledAsConstructor()) { |
| 143 array = JSArray::cast(*receiver); | 143 array = JSArray::cast(*receiver); |
| 144 } else { | 144 } else { |
| 145 // Allocate the JS Array | 145 // Allocate the JS Array |
| 146 JSFunction* constructor = | 146 JSFunction* constructor = |
| 147 Top::context()->global_context()->array_function(); | 147 Top::context()->global_context()->array_function(); |
| 148 Object* obj = Heap::AllocateJSObject(constructor); | 148 Object* obj = Heap::AllocateJSObject(constructor); |
| 149 if (obj->IsFailure()) return obj; | 149 if (obj->IsFailure()) return obj; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 return holder; | 319 return holder; |
| 320 } | 320 } |
| 321 | 321 |
| 322 | 322 |
| 323 BUILTIN(HandleApiCall) { | 323 BUILTIN(HandleApiCall) { |
| 324 HandleScope scope; | 324 HandleScope scope; |
| 325 bool is_construct = CalledAsConstructor(); | 325 bool is_construct = CalledAsConstructor(); |
| 326 | 326 |
| 327 // TODO(428): Remove use of static variable, handle API callbacks directly. | 327 // TODO(428): Remove use of static variable, handle API callbacks directly. |
| 328 Handle<JSFunction> function = | 328 Handle<JSFunction> function = |
| 329 Handle<JSFunction>(JSFunction::cast(Builtins::builtin_passed_function)); | 329 Handle<JSFunction>(JSFunction::cast( |
| 330 v8_context()->builtins_data_.builtin_passed_function_)); |
| 330 | 331 |
| 331 if (is_construct) { | 332 if (is_construct) { |
| 332 Handle<FunctionTemplateInfo> desc = | 333 Handle<FunctionTemplateInfo> desc = |
| 333 Handle<FunctionTemplateInfo>( | 334 Handle<FunctionTemplateInfo>( |
| 334 FunctionTemplateInfo::cast(function->shared()->function_data())); | 335 FunctionTemplateInfo::cast(function->shared()->function_data())); |
| 335 bool pending_exception = false; | 336 bool pending_exception = false; |
| 336 Factory::ConfigureInstance(desc, Handle<JSObject>::cast(receiver), | 337 Factory::ConfigureInstance(desc, Handle<JSObject>::cast(receiver), |
| 337 &pending_exception); | 338 &pending_exception); |
| 338 ASSERT(Top::has_pending_exception() == pending_exception); | 339 ASSERT(Top::has_pending_exception() == pending_exception); |
| 339 if (pending_exception) return Failure::Exception(); | 340 if (pending_exception) return Failure::Exception(); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 | 476 |
| 476 | 477 |
| 477 // Handle calls to non-function objects created through the API. This delegate | 478 // Handle calls to non-function objects created through the API. This delegate |
| 478 // function is used when the call is a construct call. | 479 // function is used when the call is a construct call. |
| 479 BUILTIN(HandleApiCallAsConstructor) { | 480 BUILTIN(HandleApiCallAsConstructor) { |
| 480 return HandleApiCallAsFunctionOrConstructor(true, args); | 481 return HandleApiCallAsFunctionOrConstructor(true, args); |
| 481 } | 482 } |
| 482 BUILTIN_END | 483 BUILTIN_END |
| 483 | 484 |
| 484 | 485 |
| 485 // TODO(1238487): This is a nasty hack. We need to improve the way we | |
| 486 // call builtins considerable to get rid of this and the hairy macros | |
| 487 // in builtins.cc. | |
| 488 Object* Builtins::builtin_passed_function; | |
| 489 | |
| 490 | |
| 491 | 486 |
| 492 static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) { | 487 static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) { |
| 493 LoadIC::GenerateArrayLength(masm); | 488 LoadIC::GenerateArrayLength(masm); |
| 494 } | 489 } |
| 495 | 490 |
| 496 | 491 |
| 497 static void Generate_LoadIC_StringLength(MacroAssembler* masm) { | 492 static void Generate_LoadIC_StringLength(MacroAssembler* masm) { |
| 498 LoadIC::GenerateStringLength(masm); | 493 LoadIC::GenerateStringLength(masm); |
| 499 } | 494 } |
| 500 | 495 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 static void Generate_Return_DebugBreak(MacroAssembler* masm) { | 688 static void Generate_Return_DebugBreak(MacroAssembler* masm) { |
| 694 Debug::GenerateReturnDebugBreak(masm); | 689 Debug::GenerateReturnDebugBreak(masm); |
| 695 } | 690 } |
| 696 | 691 |
| 697 | 692 |
| 698 static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) { | 693 static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) { |
| 699 Debug::GenerateStubNoRegistersDebugBreak(masm); | 694 Debug::GenerateStubNoRegistersDebugBreak(masm); |
| 700 } | 695 } |
| 701 #endif | 696 #endif |
| 702 | 697 |
| 703 Object* Builtins::builtins_[builtin_count] = { NULL, }; | 698 BuiltinsData::BuiltinsData() |
| 704 const char* Builtins::names_[builtin_count] = { NULL, }; | 699 :is_initialized_(false), builtin_passed_function_(NULL) { |
| 700 for (int i = 0; i < builtin_count; ++i) { |
| 701 builtins_[i] = NULL; |
| 702 names_[i] = NULL; |
| 703 } |
| 704 } |
| 705 | 705 |
| 706 #define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name), | 706 #define DEF_ENUM_C(name) FUNCTION_ADDR(Builtin_##name), |
| 707 Address Builtins::c_functions_[cfunction_count] = { | 707 Address Builtins::c_functions_[cfunction_count] = { |
| 708 BUILTIN_LIST_C(DEF_ENUM_C) | 708 BUILTIN_LIST_C(DEF_ENUM_C) |
| 709 }; | 709 }; |
| 710 #undef DEF_ENUM_C | 710 #undef DEF_ENUM_C |
| 711 | 711 |
| 712 #define DEF_JS_NAME(name, ignore) #name, | 712 #define DEF_JS_NAME(name, ignore) #name, |
| 713 #define DEF_JS_ARGC(ignore, argc) argc, | 713 #define DEF_JS_ARGC(ignore, argc) argc, |
| 714 const char* Builtins::javascript_names_[id_count] = { | 714 const char* Builtins::javascript_names_[id_count] = { |
| 715 BUILTINS_LIST_JS(DEF_JS_NAME) | 715 BUILTINS_LIST_JS(DEF_JS_NAME) |
| 716 }; | 716 }; |
| 717 | 717 |
| 718 int Builtins::javascript_argc_[id_count] = { | 718 int Builtins::javascript_argc_[id_count] = { |
| 719 BUILTINS_LIST_JS(DEF_JS_ARGC) | 719 BUILTINS_LIST_JS(DEF_JS_ARGC) |
| 720 }; | 720 }; |
| 721 #undef DEF_JS_NAME | 721 #undef DEF_JS_NAME |
| 722 #undef DEF_JS_ARGC | 722 #undef DEF_JS_ARGC |
| 723 | 723 |
| 724 static bool is_initialized = false; | |
| 725 void Builtins::Setup(bool create_heap_objects) { | 724 void Builtins::Setup(bool create_heap_objects) { |
| 726 ASSERT(!is_initialized); | 725 BuiltinsData& data = v8_context()->builtins_data_; |
| 726 ASSERT(!data.is_initialized_); |
| 727 | 727 |
| 728 // Create a scope for the handles in the builtins. | 728 // Create a scope for the handles in the builtins. |
| 729 HandleScope scope; | 729 HandleScope scope; |
| 730 | 730 |
| 731 struct BuiltinDesc { | 731 struct BuiltinDesc { |
| 732 byte* generator; | 732 byte* generator; |
| 733 byte* c_code; | 733 byte* c_code; |
| 734 const char* s_name; // name is only used for generating log information. | 734 const char* s_name; // name is only used for generating log information. |
| 735 int name; | 735 int name; |
| 736 Code::Flags flags; | 736 Code::Flags flags; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 if (code->IsFailure()) { | 793 if (code->IsFailure()) { |
| 794 v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); | 794 v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); |
| 795 } | 795 } |
| 796 } | 796 } |
| 797 // Add any unresolved jumps or calls to the fixup list in the | 797 // Add any unresolved jumps or calls to the fixup list in the |
| 798 // bootstrapper. | 798 // bootstrapper. |
| 799 Bootstrapper::AddFixup(Code::cast(code), &masm); | 799 Bootstrapper::AddFixup(Code::cast(code), &masm); |
| 800 // Log the event and add the code to the builtins array. | 800 // Log the event and add the code to the builtins array. |
| 801 LOG(CodeCreateEvent(Logger::BUILTIN_TAG, | 801 LOG(CodeCreateEvent(Logger::BUILTIN_TAG, |
| 802 Code::cast(code), functions[i].s_name)); | 802 Code::cast(code), functions[i].s_name)); |
| 803 builtins_[i] = code; | 803 data.builtins_[i] = code; |
| 804 #ifdef ENABLE_DISASSEMBLER | 804 #ifdef ENABLE_DISASSEMBLER |
| 805 if (FLAG_print_builtin_code) { | 805 if (FLAG_print_builtin_code) { |
| 806 PrintF("Builtin: %s\n", functions[i].s_name); | 806 PrintF("Builtin: %s\n", functions[i].s_name); |
| 807 Code::cast(code)->Disassemble(functions[i].s_name); | 807 Code::cast(code)->Disassemble(functions[i].s_name); |
| 808 PrintF("\n"); | 808 PrintF("\n"); |
| 809 } | 809 } |
| 810 #endif | 810 #endif |
| 811 } else { | 811 } else { |
| 812 // Deserializing. The values will be filled in during IterateBuiltins. | 812 // Deserializing. The values will be filled in during IterateBuiltins. |
| 813 builtins_[i] = NULL; | 813 data.builtins_[i] = NULL; |
| 814 } | 814 } |
| 815 names_[i] = functions[i].s_name; | 815 data.names_[i] = functions[i].s_name; |
| 816 } | 816 } |
| 817 | 817 |
| 818 // Mark as initialized. | 818 // Mark as initialized. |
| 819 is_initialized = true; | 819 data.is_initialized_ = true; |
| 820 } | 820 } |
| 821 | 821 |
| 822 | 822 |
| 823 void Builtins::TearDown() { | 823 void Builtins::TearDown() { |
| 824 is_initialized = false; | 824 v8_context()->builtins_data_.is_initialized_ = false; |
| 825 } | 825 } |
| 826 | 826 |
| 827 | 827 |
| 828 void Builtins::IterateBuiltins(ObjectVisitor* v) { | 828 void Builtins::IterateBuiltins(ObjectVisitor* v) { |
| 829 v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); | 829 BuiltinsData& data = v8_context()->builtins_data_; |
| 830 v->VisitPointers(&data.builtins_[0], &data.builtins_[0] + builtin_count); |
| 830 } | 831 } |
| 831 | 832 |
| 832 | 833 |
| 833 const char* Builtins::Lookup(byte* pc) { | 834 const char* Builtins::Lookup(byte* pc) { |
| 834 if (is_initialized) { // may be called during initialization (disassembler!) | 835 BuiltinsData& data = v8_context()->builtins_data_; |
| 836 if (data.is_initialized_) { |
| 837 // may be called during initialization (disassembler!) |
| 835 for (int i = 0; i < builtin_count; i++) { | 838 for (int i = 0; i < builtin_count; i++) { |
| 836 Code* entry = Code::cast(builtins_[i]); | 839 Code* entry = Code::cast(data.builtins_[i]); |
| 837 if (entry->contains(pc)) { | 840 if (entry->contains(pc)) { |
| 838 return names_[i]; | 841 return data.names_[i]; |
| 839 } | 842 } |
| 840 } | 843 } |
| 841 } | 844 } |
| 842 return NULL; | 845 return NULL; |
| 843 } | 846 } |
| 844 | 847 |
| 845 | 848 |
| 846 } } // namespace v8::internal | 849 } } // namespace v8::internal |
| OLD | NEW |