OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/extensions/externalize-string-extension.h" | 9 #include "src/extensions/externalize-string-extension.h" |
10 #include "src/extensions/free-buffer-extension.h" | 10 #include "src/extensions/free-buffer-extension.h" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 | 176 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 |
177 Handle<JSFunction> GetStrictPoisonFunction(); | 177 Handle<JSFunction> GetStrictPoisonFunction(); |
178 // Poison for sloppy generator function arguments/callee. | 178 // Poison for sloppy generator function arguments/callee. |
179 Handle<JSFunction> GetGeneratorPoisonFunction(); | 179 Handle<JSFunction> GetGeneratorPoisonFunction(); |
180 | 180 |
181 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); | 181 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); |
182 | 182 |
183 // Make the "arguments" and "caller" properties throw a TypeError on access. | 183 // Make the "arguments" and "caller" properties throw a TypeError on access. |
184 void PoisonArgumentsAndCaller(Handle<Map> map); | 184 void PoisonArgumentsAndCaller(Handle<Map> map); |
185 | 185 |
186 // Creates the global objects using the global and the template passed in | 186 // Creates the global objects using the global proxy and the template passed |
187 // through the API. We call this regardless of whether we are building a | 187 // in through the API. We call this regardless of whether we are building a |
188 // context from scratch or using a deserialized one from the partial snapshot | 188 // context from scratch or using a deserialized one from the partial snapshot |
189 // but in the latter case we don't use the objects it produces directly, as | 189 // but in the latter case we don't use the objects it produces directly, as |
190 // we have to used the deserialized ones that are linked together with the | 190 // we have to used the deserialized ones that are linked together with the |
191 // rest of the context snapshot. | 191 // rest of the context snapshot. |
192 Handle<JSGlobalProxy> CreateNewGlobals( | 192 Handle<GlobalObject> CreateNewGlobals( |
193 v8::Handle<v8::ObjectTemplate> global_proxy_template, | 193 v8::Handle<v8::ObjectTemplate> global_proxy_template, |
194 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 194 Handle<JSGlobalProxy> global_proxy); |
195 Handle<GlobalObject>* global_object_out); | |
196 // Hooks the given global proxy into the context. If the context was created | 195 // Hooks the given global proxy into the context. If the context was created |
197 // by deserialization then this will unhook the global proxy that was | 196 // by deserialization then this will unhook the global proxy that was |
198 // deserialized, leaving the GC to pick it up. | 197 // deserialized, leaving the GC to pick it up. |
199 void HookUpGlobalProxy(Handle<GlobalObject> global_object, | 198 void HookUpGlobalProxy(Handle<GlobalObject> global_object, |
200 Handle<JSGlobalProxy> global_proxy); | 199 Handle<JSGlobalProxy> global_proxy); |
201 // Similarly, we want to use the global that has been created by the templates | 200 // Similarly, we want to use the global that has been created by the templates |
202 // passed through the API. The global from the snapshot is detached from the | 201 // passed through the API. The global from the snapshot is detached from the |
203 // other objects in the snapshot. | 202 // other objects in the snapshot. |
204 void HookUpGlobalObject(Handle<GlobalObject> global_object, | 203 void HookUpGlobalObject(Handle<GlobalObject> global_object, |
205 Handle<FixedArray> outdated_contexts); | 204 Handle<FixedArray> outdated_contexts); |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 isolate()->set_context(*native_context()); | 749 isolate()->set_context(*native_context()); |
751 | 750 |
752 // Allocate the message listeners object. | 751 // Allocate the message listeners object. |
753 { | 752 { |
754 v8::NeanderArray listeners(isolate()); | 753 v8::NeanderArray listeners(isolate()); |
755 native_context()->set_message_listeners(*listeners.value()); | 754 native_context()->set_message_listeners(*listeners.value()); |
756 } | 755 } |
757 } | 756 } |
758 | 757 |
759 | 758 |
760 Handle<JSGlobalProxy> Genesis::CreateNewGlobals( | 759 Handle<GlobalObject> Genesis::CreateNewGlobals( |
761 v8::Handle<v8::ObjectTemplate> global_proxy_template, | 760 v8::Handle<v8::ObjectTemplate> global_proxy_template, |
762 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 761 Handle<JSGlobalProxy> global_proxy) { |
763 Handle<GlobalObject>* global_object_out) { | |
764 // The argument global_proxy_template aka data is an ObjectTemplateInfo. | 762 // The argument global_proxy_template aka data is an ObjectTemplateInfo. |
765 // It has a constructor pointer that points at global_constructor which is a | 763 // It has a constructor pointer that points at global_constructor which is a |
766 // FunctionTemplateInfo. | 764 // FunctionTemplateInfo. |
767 // The global_proxy_constructor is used to create or reinitialize the | 765 // The global_proxy_constructor is used to (re)initialize the |
768 // global_proxy. The global_proxy_constructor also has a prototype_template | 766 // global_proxy. The global_proxy_constructor also has a prototype_template |
769 // pointer that points at js_global_object_template which is an | 767 // pointer that points at js_global_object_template which is an |
770 // ObjectTemplateInfo. | 768 // ObjectTemplateInfo. |
771 // That in turn has a constructor pointer that points at | 769 // That in turn has a constructor pointer that points at |
772 // js_global_object_constructor which is a FunctionTemplateInfo. | 770 // js_global_object_constructor which is a FunctionTemplateInfo. |
773 // js_global_object_constructor is used to make js_global_object_function | 771 // js_global_object_constructor is used to make js_global_object_function |
774 // js_global_object_function is used to make the new global_object. | 772 // js_global_object_function is used to make the new global_object. |
775 // | 773 // |
776 // --- G l o b a l --- | 774 // --- G l o b a l --- |
777 // Step 1: Create a fresh JSGlobalObject. | 775 // Step 1: Create a fresh JSGlobalObject. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 js_global_object_function = | 811 js_global_object_function = |
814 factory()->CreateApiFunction(js_global_object_constructor, | 812 factory()->CreateApiFunction(js_global_object_constructor, |
815 factory()->the_hole_value(), | 813 factory()->the_hole_value(), |
816 factory()->GlobalObjectType); | 814 factory()->GlobalObjectType); |
817 } | 815 } |
818 | 816 |
819 js_global_object_function->initial_map()->set_is_hidden_prototype(); | 817 js_global_object_function->initial_map()->set_is_hidden_prototype(); |
820 js_global_object_function->initial_map()->set_dictionary_map(true); | 818 js_global_object_function->initial_map()->set_dictionary_map(true); |
821 Handle<GlobalObject> global_object = | 819 Handle<GlobalObject> global_object = |
822 factory()->NewGlobalObject(js_global_object_function); | 820 factory()->NewGlobalObject(js_global_object_function); |
823 if (global_object_out != NULL) { | |
824 *global_object_out = global_object; | |
825 } | |
826 | 821 |
827 // Step 2: create or re-initialize the global proxy object. | 822 // Step 2: (re)initialize the global proxy object. |
828 Handle<JSFunction> global_proxy_function; | 823 Handle<JSFunction> global_proxy_function; |
829 if (global_proxy_template.IsEmpty()) { | 824 if (global_proxy_template.IsEmpty()) { |
830 Handle<String> name = Handle<String>(heap()->empty_string()); | 825 Handle<String> name = Handle<String>(heap()->empty_string()); |
831 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin( | 826 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin( |
832 Builtins::kIllegal)); | 827 Builtins::kIllegal)); |
833 global_proxy_function = factory()->NewFunction( | 828 global_proxy_function = factory()->NewFunction( |
834 name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize); | 829 name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize); |
835 } else { | 830 } else { |
836 Handle<ObjectTemplateInfo> data = | 831 Handle<ObjectTemplateInfo> data = |
837 v8::Utils::OpenHandle(*global_proxy_template); | 832 v8::Utils::OpenHandle(*global_proxy_template); |
838 Handle<FunctionTemplateInfo> global_constructor( | 833 Handle<FunctionTemplateInfo> global_constructor( |
839 FunctionTemplateInfo::cast(data->constructor())); | 834 FunctionTemplateInfo::cast(data->constructor())); |
840 global_proxy_function = | 835 global_proxy_function = |
841 factory()->CreateApiFunction(global_constructor, | 836 factory()->CreateApiFunction(global_constructor, |
842 factory()->the_hole_value(), | 837 factory()->the_hole_value(), |
843 factory()->GlobalProxyType); | 838 factory()->GlobalProxyType); |
844 } | 839 } |
845 | 840 |
846 Handle<String> global_name = factory()->global_string(); | 841 Handle<String> global_name = factory()->global_string(); |
847 global_proxy_function->shared()->set_instance_class_name(*global_name); | 842 global_proxy_function->shared()->set_instance_class_name(*global_name); |
848 global_proxy_function->initial_map()->set_is_access_check_needed(true); | 843 global_proxy_function->initial_map()->set_is_access_check_needed(true); |
849 | 844 |
850 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects | 845 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects |
851 // Return the global proxy. | 846 // Return the global proxy. |
852 | 847 |
853 Handle<JSGlobalProxy> global_proxy; | 848 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); |
854 if (maybe_global_proxy.ToHandle(&global_proxy)) { | 849 return global_object; |
855 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); | |
856 } else { | |
857 global_proxy = Handle<JSGlobalProxy>::cast( | |
858 factory()->NewJSObject(global_proxy_function, TENURED)); | |
859 global_proxy->set_hash(heap()->undefined_value()); | |
860 } | |
861 return global_proxy; | |
862 } | 850 } |
863 | 851 |
864 | 852 |
865 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> global_object, | 853 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> global_object, |
866 Handle<JSGlobalProxy> global_proxy) { | 854 Handle<JSGlobalProxy> global_proxy) { |
867 // Set the native context for the global object. | 855 // Set the native context for the global object. |
868 global_object->set_native_context(*native_context()); | 856 global_object->set_native_context(*native_context()); |
869 global_object->set_global_proxy(*global_proxy); | 857 global_object->set_global_proxy(*global_proxy); |
870 global_proxy->set_native_context(*native_context()); | 858 global_proxy->set_native_context(*native_context()); |
| 859 // If we deserialized the context, the global proxy is already |
| 860 // correctly set up. Otherwise it's undefined. |
| 861 DCHECK(native_context()->get(Context::GLOBAL_PROXY_INDEX)->IsUndefined() || |
| 862 native_context()->global_proxy() == *global_proxy); |
871 native_context()->set_global_proxy(*global_proxy); | 863 native_context()->set_global_proxy(*global_proxy); |
872 } | 864 } |
873 | 865 |
874 | 866 |
875 void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object, | 867 void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object, |
876 Handle<FixedArray> outdated_contexts) { | 868 Handle<FixedArray> outdated_contexts) { |
877 Handle<GlobalObject> global_object_from_snapshot( | 869 Handle<GlobalObject> global_object_from_snapshot( |
878 GlobalObject::cast(native_context()->extension())); | 870 GlobalObject::cast(native_context()->extension())); |
879 Handle<JSBuiltinsObject> builtins_global(native_context()->builtins()); | 871 Handle<JSBuiltinsObject> builtins_global(native_context()->builtins()); |
880 native_context()->set_extension(*global_object); | 872 native_context()->set_extension(*global_object); |
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2729 // Before creating the roots we must save the context and restore it | 2721 // Before creating the roots we must save the context and restore it |
2730 // on all function exits. | 2722 // on all function exits. |
2731 SaveContext saved_context(isolate); | 2723 SaveContext saved_context(isolate); |
2732 | 2724 |
2733 // During genesis, the boilerplate for stack overflow won't work until the | 2725 // During genesis, the boilerplate for stack overflow won't work until the |
2734 // environment has been at least partially initialized. Add a stack check | 2726 // environment has been at least partially initialized. Add a stack check |
2735 // before entering JS code to catch overflow early. | 2727 // before entering JS code to catch overflow early. |
2736 StackLimitCheck check(isolate); | 2728 StackLimitCheck check(isolate); |
2737 if (check.HasOverflowed()) return; | 2729 if (check.HasOverflowed()) return; |
2738 | 2730 |
| 2731 // The deserializer needs to hook up references to the global proxy. |
| 2732 // Create an uninitialized global proxy now if we don't have one |
| 2733 // and initialize it later in CreateNewGlobals. |
| 2734 Handle<JSGlobalProxy> global_proxy; |
| 2735 if (!maybe_global_proxy.ToHandle(&global_proxy)) { |
| 2736 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy(); |
| 2737 } |
| 2738 |
2739 // We can only de-serialize a context if the isolate was initialized from | 2739 // We can only de-serialize a context if the isolate was initialized from |
2740 // a snapshot. Otherwise we have to build the context from scratch. | 2740 // a snapshot. Otherwise we have to build the context from scratch. |
2741 Handle<FixedArray> outdated_contexts; | 2741 Handle<FixedArray> outdated_contexts; |
2742 if (!isolate->initialized_from_snapshot() || | 2742 if (!isolate->initialized_from_snapshot() || |
2743 !Snapshot::NewContextFromSnapshot(isolate, &outdated_contexts) | 2743 !Snapshot::NewContextFromSnapshot(isolate, global_proxy, |
| 2744 &outdated_contexts) |
2744 .ToHandle(&native_context_)) { | 2745 .ToHandle(&native_context_)) { |
2745 native_context_ = Handle<Context>(); | 2746 native_context_ = Handle<Context>(); |
2746 } | 2747 } |
2747 | 2748 |
2748 if (!native_context().is_null()) { | 2749 if (!native_context().is_null()) { |
2749 AddToWeakNativeContextList(*native_context()); | 2750 AddToWeakNativeContextList(*native_context()); |
2750 isolate->set_context(*native_context()); | 2751 isolate->set_context(*native_context()); |
2751 isolate->counters()->contexts_created_by_snapshot()->Increment(); | 2752 isolate->counters()->contexts_created_by_snapshot()->Increment(); |
2752 #if TRACE_MAPS | 2753 #if TRACE_MAPS |
2753 if (FLAG_trace_maps) { | 2754 if (FLAG_trace_maps) { |
2754 Handle<JSFunction> object_fun = isolate->object_function(); | 2755 Handle<JSFunction> object_fun = isolate->object_function(); |
2755 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n", | 2756 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n", |
2756 reinterpret_cast<void*>(object_fun->initial_map()), | 2757 reinterpret_cast<void*>(object_fun->initial_map()), |
2757 object_fun->shared()->unique_id()); | 2758 object_fun->shared()->unique_id()); |
2758 Map::TraceAllTransitions(object_fun->initial_map()); | 2759 Map::TraceAllTransitions(object_fun->initial_map()); |
2759 } | 2760 } |
2760 #endif | 2761 #endif |
2761 Handle<GlobalObject> global_object; | 2762 Handle<GlobalObject> global_object = |
2762 Handle<JSGlobalProxy> global_proxy = CreateNewGlobals( | 2763 CreateNewGlobals(global_proxy_template, global_proxy); |
2763 global_proxy_template, maybe_global_proxy, &global_object); | |
2764 | 2764 |
2765 HookUpGlobalProxy(global_object, global_proxy); | 2765 HookUpGlobalProxy(global_object, global_proxy); |
2766 HookUpGlobalObject(global_object, outdated_contexts); | 2766 HookUpGlobalObject(global_object, outdated_contexts); |
2767 native_context()->builtins()->set_global_proxy( | 2767 native_context()->builtins()->set_global_proxy( |
2768 native_context()->global_proxy()); | 2768 native_context()->global_proxy()); |
2769 | 2769 |
2770 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 2770 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
2771 } else { | 2771 } else { |
2772 // We get here if there was no context snapshot. | 2772 // We get here if there was no context snapshot. |
2773 CreateRoots(); | 2773 CreateRoots(); |
2774 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); | 2774 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); |
2775 CreateStrictModeFunctionMaps(empty_function); | 2775 CreateStrictModeFunctionMaps(empty_function); |
2776 Handle<GlobalObject> global_object; | 2776 Handle<GlobalObject> global_object = |
2777 Handle<JSGlobalProxy> global_proxy = CreateNewGlobals( | 2777 CreateNewGlobals(global_proxy_template, global_proxy); |
2778 global_proxy_template, maybe_global_proxy, &global_object); | |
2779 HookUpGlobalProxy(global_object, global_proxy); | 2778 HookUpGlobalProxy(global_object, global_proxy); |
2780 InitializeGlobal(global_object, empty_function); | 2779 InitializeGlobal(global_object, empty_function); |
2781 InstallJSFunctionResultCaches(); | 2780 InstallJSFunctionResultCaches(); |
2782 InitializeNormalizedMapCaches(); | 2781 InitializeNormalizedMapCaches(); |
2783 if (!InstallNatives()) return; | 2782 if (!InstallNatives()) return; |
2784 | 2783 |
2785 MakeFunctionInstancePrototypeWritable(); | 2784 MakeFunctionInstancePrototypeWritable(); |
2786 | 2785 |
2787 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 2786 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
2788 isolate->counters()->contexts_created_from_scratch()->Increment(); | 2787 isolate->counters()->contexts_created_from_scratch()->Increment(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2856 return from + sizeof(NestingCounterType); | 2855 return from + sizeof(NestingCounterType); |
2857 } | 2856 } |
2858 | 2857 |
2859 | 2858 |
2860 // Called when the top-level V8 mutex is destroyed. | 2859 // Called when the top-level V8 mutex is destroyed. |
2861 void Bootstrapper::FreeThreadResources() { | 2860 void Bootstrapper::FreeThreadResources() { |
2862 DCHECK(!IsActive()); | 2861 DCHECK(!IsActive()); |
2863 } | 2862 } |
2864 | 2863 |
2865 } } // namespace v8::internal | 2864 } } // namespace v8::internal |
OLD | NEW |