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 |