| 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 |