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