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/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/base/ieee754.h" | 9 #include "src/base/ieee754.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 void CreateAsyncFunctionMaps(Handle<JSFunction> empty); | 170 void CreateAsyncFunctionMaps(Handle<JSFunction> empty); |
171 void CreateJSProxyMaps(); | 171 void CreateJSProxyMaps(); |
172 | 172 |
173 // Make the "arguments" and "caller" properties throw a TypeError on access. | 173 // Make the "arguments" and "caller" properties throw a TypeError on access. |
174 void AddRestrictedFunctionProperties(Handle<JSFunction> empty); | 174 void AddRestrictedFunctionProperties(Handle<JSFunction> empty); |
175 | 175 |
176 // Creates the global objects using the global proxy and the template passed | 176 // Creates the global objects using the global proxy and the template passed |
177 // in through the API. We call this regardless of whether we are building a | 177 // in through the API. We call this regardless of whether we are building a |
178 // context from scratch or using a deserialized one from the partial snapshot | 178 // context from scratch or using a deserialized one from the partial snapshot |
179 // but in the latter case we don't use the objects it produces directly, as | 179 // but in the latter case we don't use the objects it produces directly, as |
180 // we have to used the deserialized ones that are linked together with the | 180 // we have to use the deserialized ones that are linked together with the |
181 // rest of the context snapshot. | 181 // rest of the context snapshot. At the end we link the global proxy and the |
| 182 // context to each other. |
182 Handle<JSGlobalObject> CreateNewGlobals( | 183 Handle<JSGlobalObject> CreateNewGlobals( |
183 v8::Local<v8::ObjectTemplate> global_proxy_template, | 184 v8::Local<v8::ObjectTemplate> global_proxy_template, |
184 Handle<JSGlobalProxy> global_proxy); | 185 Handle<JSGlobalProxy> global_proxy); |
185 // Hooks the given global proxy into the context. If the context was created | |
186 // by deserialization then this will unhook the global proxy that was | |
187 // deserialized, leaving the GC to pick it up. | |
188 void HookUpGlobalProxy(Handle<JSGlobalObject> global_object, | |
189 Handle<JSGlobalProxy> global_proxy); | |
190 // Similarly, we want to use the global that has been created by the templates | 186 // Similarly, we want to use the global that has been created by the templates |
191 // passed through the API. The global from the snapshot is detached from the | 187 // passed through the API. The global from the snapshot is detached from the |
192 // other objects in the snapshot. | 188 // other objects in the snapshot. |
193 void HookUpGlobalObject(Handle<JSGlobalObject> global_object); | 189 void HookUpGlobalObject(Handle<JSGlobalObject> global_object); |
| 190 // Hooks the given global proxy into the context in the case we do not |
| 191 // replace the global object from the deserialized native context. |
| 192 void HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy); |
194 // The native context has a ScriptContextTable that store declarative bindings | 193 // The native context has a ScriptContextTable that store declarative bindings |
195 // made in script scopes. Add a "this" binding to that table pointing to the | 194 // made in script scopes. Add a "this" binding to that table pointing to the |
196 // global proxy. | 195 // global proxy. |
197 void InstallGlobalThisBinding(); | 196 void InstallGlobalThisBinding(); |
198 // New context initialization. Used for creating a context from scratch. | 197 // New context initialization. Used for creating a context from scratch. |
199 void InitializeGlobal(Handle<JSGlobalObject> global_object, | 198 void InitializeGlobal(Handle<JSGlobalObject> global_object, |
200 Handle<JSFunction> empty_function, | 199 Handle<JSFunction> empty_function, |
201 GlobalContextType context_type); | 200 GlobalContextType context_type); |
202 void InitializeExperimentalGlobal(); | 201 void InitializeExperimentalGlobal(); |
203 // Depending on the situation, expose and/or get rid of the utils object. | 202 // Depending on the situation, expose and/or get rid of the utils object. |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 Handle<FunctionTemplateInfo> global_constructor( | 982 Handle<FunctionTemplateInfo> global_constructor( |
984 FunctionTemplateInfo::cast(data->constructor())); | 983 FunctionTemplateInfo::cast(data->constructor())); |
985 global_proxy_function = ApiNatives::CreateApiFunction( | 984 global_proxy_function = ApiNatives::CreateApiFunction( |
986 isolate(), global_constructor, factory()->the_hole_value(), | 985 isolate(), global_constructor, factory()->the_hole_value(), |
987 ApiNatives::GlobalProxyType); | 986 ApiNatives::GlobalProxyType); |
988 } | 987 } |
989 Handle<String> global_name = factory()->global_string(); | 988 Handle<String> global_name = factory()->global_string(); |
990 global_proxy_function->shared()->set_instance_class_name(*global_name); | 989 global_proxy_function->shared()->set_instance_class_name(*global_name); |
991 global_proxy_function->initial_map()->set_is_access_check_needed(true); | 990 global_proxy_function->initial_map()->set_is_access_check_needed(true); |
992 global_proxy_function->initial_map()->set_has_hidden_prototype(true); | 991 global_proxy_function->initial_map()->set_has_hidden_prototype(true); |
| 992 native_context()->set_global_proxy_function(*global_proxy_function); |
993 | 993 |
994 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects | 994 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects |
995 // Return the global proxy. | 995 // Return the global proxy. |
996 | 996 |
997 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); | 997 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); |
998 return global_object; | |
999 } | |
1000 | 998 |
1001 | |
1002 void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object, | |
1003 Handle<JSGlobalProxy> global_proxy) { | |
1004 // Set the native context for the global object. | 999 // Set the native context for the global object. |
1005 global_object->set_native_context(*native_context()); | 1000 global_object->set_native_context(*native_context()); |
1006 global_object->set_global_proxy(*global_proxy); | 1001 global_object->set_global_proxy(*global_proxy); |
| 1002 // Set the native context of the global proxy. |
1007 global_proxy->set_native_context(*native_context()); | 1003 global_proxy->set_native_context(*native_context()); |
1008 // If we deserialized the context, the global proxy is already | 1004 // Set the global proxy of the native context. If the native context has been |
1009 // correctly set up. Otherwise it's undefined. | 1005 // deserialized, the global proxy is already correctly set up by the |
| 1006 // deserializer. Otherwise it's undefined. |
1010 DCHECK(native_context() | 1007 DCHECK(native_context() |
1011 ->get(Context::GLOBAL_PROXY_INDEX) | 1008 ->get(Context::GLOBAL_PROXY_INDEX) |
1012 ->IsUndefined(isolate()) || | 1009 ->IsUndefined(isolate()) || |
1013 native_context()->global_proxy() == *global_proxy); | 1010 native_context()->global_proxy() == *global_proxy); |
1014 native_context()->set_global_proxy(*global_proxy); | 1011 native_context()->set_global_proxy(*global_proxy); |
| 1012 |
| 1013 return global_object; |
1015 } | 1014 } |
1016 | 1015 |
| 1016 void Genesis::HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy) { |
| 1017 // Re-initialize the global proxy with the global proxy function from the |
| 1018 // snapshot, and then set up the link to the native context. |
| 1019 Handle<JSFunction> global_proxy_function( |
| 1020 native_context()->global_proxy_function()); |
| 1021 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); |
| 1022 Handle<JSObject> global_object( |
| 1023 JSObject::cast(native_context()->global_object())); |
| 1024 JSObject::ForceSetPrototype(global_proxy, global_object); |
| 1025 global_proxy->set_native_context(*native_context()); |
| 1026 DCHECK(native_context()->global_proxy() == *global_proxy); |
| 1027 } |
1017 | 1028 |
1018 void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) { | 1029 void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) { |
1019 Handle<JSGlobalObject> global_object_from_snapshot( | 1030 Handle<JSGlobalObject> global_object_from_snapshot( |
1020 JSGlobalObject::cast(native_context()->extension())); | 1031 JSGlobalObject::cast(native_context()->extension())); |
1021 native_context()->set_extension(*global_object); | 1032 native_context()->set_extension(*global_object); |
1022 native_context()->set_security_token(*global_object); | 1033 native_context()->set_security_token(*global_object); |
1023 | 1034 |
1024 TransferNamedProperties(global_object_from_snapshot, global_object); | 1035 TransferNamedProperties(global_object_from_snapshot, global_object); |
1025 TransferIndexedProperties(global_object_from_snapshot, global_object); | 1036 TransferIndexedProperties(global_object_from_snapshot, global_object); |
1026 } | 1037 } |
(...skipping 3417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4444 }; | 4455 }; |
4445 | 4456 |
4446 Genesis::Genesis(Isolate* isolate, | 4457 Genesis::Genesis(Isolate* isolate, |
4447 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 4458 MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
4448 v8::Local<v8::ObjectTemplate> global_proxy_template, | 4459 v8::Local<v8::ObjectTemplate> global_proxy_template, |
4449 size_t context_snapshot_index, GlobalContextType context_type) | 4460 size_t context_snapshot_index, GlobalContextType context_type) |
4450 : isolate_(isolate), active_(isolate->bootstrapper()) { | 4461 : isolate_(isolate), active_(isolate->bootstrapper()) { |
4451 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); | 4462 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); |
4452 result_ = Handle<Context>::null(); | 4463 result_ = Handle<Context>::null(); |
4453 global_proxy_ = Handle<JSGlobalProxy>::null(); | 4464 global_proxy_ = Handle<JSGlobalProxy>::null(); |
4454 bool create_new_global_proxy = context_snapshot_index == 0; | |
4455 | 4465 |
4456 // Before creating the roots we must save the context and restore it | 4466 // Before creating the roots we must save the context and restore it |
4457 // on all function exits. | 4467 // on all function exits. |
4458 SaveContext saved_context(isolate); | 4468 SaveContext saved_context(isolate); |
4459 | 4469 |
4460 // During genesis, the boilerplate for stack overflow won't work until the | 4470 // During genesis, the boilerplate for stack overflow won't work until the |
4461 // environment has been at least partially initialized. Add a stack check | 4471 // environment has been at least partially initialized. Add a stack check |
4462 // before entering JS code to catch overflow early. | 4472 // before entering JS code to catch overflow early. |
4463 StackLimitCheck check(isolate); | 4473 StackLimitCheck check(isolate); |
4464 if (check.HasOverflowed()) { | 4474 if (check.HasOverflowed()) { |
4465 isolate->StackOverflow(); | 4475 isolate->StackOverflow(); |
4466 return; | 4476 return; |
4467 } | 4477 } |
4468 | 4478 |
4469 // The deserializer needs to hook up references to the global proxy. | 4479 // The deserializer needs to hook up references to the global proxy. |
4470 // Create an uninitialized global proxy now if we don't have one | 4480 // Create an uninitialized global proxy now if we don't have one |
4471 // and initialize it later in CreateNewGlobals. | 4481 // and initialize it later in CreateNewGlobals. |
4472 Handle<JSGlobalProxy> global_proxy; | 4482 Handle<JSGlobalProxy> global_proxy; |
4473 if (!maybe_global_proxy.ToHandle(&global_proxy) && create_new_global_proxy) { | 4483 if (!maybe_global_proxy.ToHandle(&global_proxy)) { |
4474 const int internal_field_count = | 4484 const int internal_field_count = |
4475 !global_proxy_template.IsEmpty() | 4485 !global_proxy_template.IsEmpty() |
4476 ? global_proxy_template->InternalFieldCount() | 4486 ? global_proxy_template->InternalFieldCount() |
4477 : 0; | 4487 : 0; |
4478 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy( | 4488 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy( |
4479 JSGlobalProxy::SizeWithInternalFields(internal_field_count)); | 4489 JSGlobalProxy::SizeWithInternalFields(internal_field_count)); |
4480 } | 4490 } |
4481 | 4491 |
4482 // We can only de-serialize a context if the isolate was initialized from | 4492 // We can only de-serialize a context if the isolate was initialized from |
4483 // a snapshot. Otherwise we have to build the context from scratch. | 4493 // a snapshot. Otherwise we have to build the context from scratch. |
(...skipping 12 matching lines...) Expand all Loading... |
4496 #if TRACE_MAPS | 4506 #if TRACE_MAPS |
4497 if (FLAG_trace_maps) { | 4507 if (FLAG_trace_maps) { |
4498 Handle<JSFunction> object_fun = isolate->object_function(); | 4508 Handle<JSFunction> object_fun = isolate->object_function(); |
4499 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n", | 4509 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n", |
4500 reinterpret_cast<void*>(object_fun->initial_map()), | 4510 reinterpret_cast<void*>(object_fun->initial_map()), |
4501 object_fun->shared()->unique_id()); | 4511 object_fun->shared()->unique_id()); |
4502 Map::TraceAllTransitions(object_fun->initial_map()); | 4512 Map::TraceAllTransitions(object_fun->initial_map()); |
4503 } | 4513 } |
4504 #endif | 4514 #endif |
4505 | 4515 |
4506 if (create_new_global_proxy) { | 4516 if (context_snapshot_index == 0) { |
4507 Handle<JSGlobalObject> global_object = | 4517 Handle<JSGlobalObject> global_object = |
4508 CreateNewGlobals(global_proxy_template, global_proxy); | 4518 CreateNewGlobals(global_proxy_template, global_proxy); |
4509 | |
4510 HookUpGlobalProxy(global_object, global_proxy); | |
4511 HookUpGlobalObject(global_object); | 4519 HookUpGlobalObject(global_object); |
4512 | 4520 |
4513 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 4521 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
| 4522 } else { |
| 4523 // The global proxy needs to be integrated into the native context. |
| 4524 HookUpGlobalProxy(global_proxy); |
4514 } | 4525 } |
| 4526 DCHECK(!global_proxy->IsDetachedFrom(native_context()->global_object())); |
4515 } else { | 4527 } else { |
| 4528 DCHECK_EQ(0u, context_snapshot_index); |
4516 // We get here if there was no context snapshot. | 4529 // We get here if there was no context snapshot. |
4517 CreateRoots(); | 4530 CreateRoots(); |
4518 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); | 4531 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); |
4519 CreateStrictModeFunctionMaps(empty_function); | 4532 CreateStrictModeFunctionMaps(empty_function); |
4520 CreateIteratorMaps(empty_function); | 4533 CreateIteratorMaps(empty_function); |
4521 CreateAsyncFunctionMaps(empty_function); | 4534 CreateAsyncFunctionMaps(empty_function); |
4522 Handle<JSGlobalObject> global_object = | 4535 Handle<JSGlobalObject> global_object = |
4523 CreateNewGlobals(global_proxy_template, global_proxy); | 4536 CreateNewGlobals(global_proxy_template, global_proxy); |
4524 HookUpGlobalProxy(global_object, global_proxy); | |
4525 InitializeGlobal(global_object, empty_function, context_type); | 4537 InitializeGlobal(global_object, empty_function, context_type); |
4526 InitializeNormalizedMapCaches(); | 4538 InitializeNormalizedMapCaches(); |
4527 | 4539 |
4528 if (!InstallNatives(context_type)) return; | 4540 if (!InstallNatives(context_type)) return; |
4529 | 4541 |
4530 MakeFunctionInstancePrototypeWritable(); | 4542 MakeFunctionInstancePrototypeWritable(); |
4531 | 4543 |
4532 if (!InstallExtraNatives()) return; | 4544 if (!InstallExtraNatives()) return; |
4533 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 4545 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
4534 | 4546 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4615 factory()->null_value()); | 4627 factory()->null_value()); |
4616 global_proxy_map->set_is_access_check_needed(true); | 4628 global_proxy_map->set_is_access_check_needed(true); |
4617 global_proxy_map->set_is_callable(); | 4629 global_proxy_map->set_is_callable(); |
4618 global_proxy_map->set_is_constructor(true); | 4630 global_proxy_map->set_is_constructor(true); |
4619 global_proxy_map->set_has_hidden_prototype(true); | 4631 global_proxy_map->set_has_hidden_prototype(true); |
4620 | 4632 |
4621 Handle<String> global_name = factory()->global_string(); | 4633 Handle<String> global_name = factory()->global_string(); |
4622 global_proxy_function->shared()->set_instance_class_name(*global_name); | 4634 global_proxy_function->shared()->set_instance_class_name(*global_name); |
4623 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); | 4635 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); |
4624 | 4636 |
4625 // HookUpGlobalProxy. | 4637 // GlobalProxy. |
4626 global_proxy->set_native_context(heap()->null_value()); | 4638 global_proxy->set_native_context(heap()->null_value()); |
4627 | 4639 |
4628 // DetachGlobal. | 4640 // DetachGlobal. |
4629 JSObject::ForceSetPrototype(global_proxy, factory()->null_value()); | 4641 JSObject::ForceSetPrototype(global_proxy, factory()->null_value()); |
4630 | 4642 |
4631 global_proxy_ = global_proxy; | 4643 global_proxy_ = global_proxy; |
4632 } | 4644 } |
4633 | 4645 |
4634 // Support for thread preemption. | 4646 // Support for thread preemption. |
4635 | 4647 |
(...skipping 18 matching lines...) Expand all Loading... |
4654 } | 4666 } |
4655 | 4667 |
4656 | 4668 |
4657 // Called when the top-level V8 mutex is destroyed. | 4669 // Called when the top-level V8 mutex is destroyed. |
4658 void Bootstrapper::FreeThreadResources() { | 4670 void Bootstrapper::FreeThreadResources() { |
4659 DCHECK(!IsActive()); | 4671 DCHECK(!IsActive()); |
4660 } | 4672 } |
4661 | 4673 |
4662 } // namespace internal | 4674 } // namespace internal |
4663 } // namespace v8 | 4675 } // namespace v8 |
OLD | NEW |