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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 ExperimentalExtraNatives::GetSourceCache(isolate_->heap())); | 133 ExperimentalExtraNatives::GetSourceCache(isolate_->heap())); |
134 | 134 |
135 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical | 135 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 class Genesis BASE_EMBEDDED { | 139 class Genesis BASE_EMBEDDED { |
140 public: | 140 public: |
141 Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 141 Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
142 v8::Local<v8::ObjectTemplate> global_proxy_template, | 142 v8::Local<v8::ObjectTemplate> global_proxy_template, |
143 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, | 143 size_t context_snapshot_index, GlobalContextType context_type); |
144 GlobalContextType context_type); | |
145 Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 144 Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
146 v8::Local<v8::ObjectTemplate> global_proxy_template); | 145 v8::Local<v8::ObjectTemplate> global_proxy_template); |
147 ~Genesis() { } | 146 ~Genesis() { } |
148 | 147 |
149 Isolate* isolate() const { return isolate_; } | 148 Isolate* isolate() const { return isolate_; } |
150 Factory* factory() const { return isolate_->factory(); } | 149 Factory* factory() const { return isolate_->factory(); } |
151 Heap* heap() const { return isolate_->heap(); } | 150 Heap* heap() const { return isolate_->heap(); } |
152 | 151 |
153 Handle<Context> result() { return result_; } | 152 Handle<Context> result() { return result_; } |
154 | 153 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 v->Synchronize(VisitorSynchronization::kExtensions); | 305 v->Synchronize(VisitorSynchronization::kExtensions); |
307 } | 306 } |
308 | 307 |
309 Handle<Context> Bootstrapper::CreateEnvironment( | 308 Handle<Context> Bootstrapper::CreateEnvironment( |
310 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 309 MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
311 v8::Local<v8::ObjectTemplate> global_proxy_template, | 310 v8::Local<v8::ObjectTemplate> global_proxy_template, |
312 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, | 311 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, |
313 GlobalContextType context_type) { | 312 GlobalContextType context_type) { |
314 HandleScope scope(isolate_); | 313 HandleScope scope(isolate_); |
315 Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template, | 314 Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template, |
316 extensions, context_snapshot_index, context_type); | 315 context_snapshot_index, context_type); |
317 Handle<Context> env = genesis.result(); | 316 Handle<Context> env = genesis.result(); |
318 if (env.is_null() || !InstallExtensions(env, extensions)) { | 317 if (env.is_null() || !InstallExtensions(env, extensions)) { |
319 return Handle<Context>(); | 318 return Handle<Context>(); |
320 } | 319 } |
321 return scope.CloseAndEscape(env); | 320 return scope.CloseAndEscape(env); |
322 } | 321 } |
323 | 322 |
324 Handle<JSGlobalProxy> Bootstrapper::NewRemoteContext( | 323 Handle<JSGlobalProxy> Bootstrapper::NewRemoteContext( |
325 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 324 MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
326 v8::Local<v8::ObjectTemplate> global_proxy_template) { | 325 v8::Local<v8::ObjectTemplate> global_proxy_template) { |
(...skipping 3811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4138 if (!result) { | 4137 if (!result) { |
4139 // We print out the name of the extension that fail to install. | 4138 // We print out the name of the extension that fail to install. |
4140 // When an error is thrown during bootstrapping we automatically print | 4139 // When an error is thrown during bootstrapping we automatically print |
4141 // the line number at which this happened to the console in the isolate | 4140 // the line number at which this happened to the console in the isolate |
4142 // error throwing functionality. | 4141 // error throwing functionality. |
4143 base::OS::PrintError("Error installing extension '%s'.\n", | 4142 base::OS::PrintError("Error installing extension '%s'.\n", |
4144 current->extension()->name()); | 4143 current->extension()->name()); |
4145 isolate->clear_pending_exception(); | 4144 isolate->clear_pending_exception(); |
4146 } | 4145 } |
4147 extension_states->set_state(current, INSTALLED); | 4146 extension_states->set_state(current, INSTALLED); |
4148 isolate->NotifyExtensionInstalled(); | |
4149 return result; | 4147 return result; |
4150 } | 4148 } |
4151 | 4149 |
4152 | 4150 |
4153 bool Genesis::ConfigureGlobalObjects( | 4151 bool Genesis::ConfigureGlobalObjects( |
4154 v8::Local<v8::ObjectTemplate> global_proxy_template) { | 4152 v8::Local<v8::ObjectTemplate> global_proxy_template) { |
4155 Handle<JSObject> global_proxy( | 4153 Handle<JSObject> global_proxy( |
4156 JSObject::cast(native_context()->global_proxy())); | 4154 JSObject::cast(native_context()->global_proxy())); |
4157 Handle<JSObject> global_object( | 4155 Handle<JSObject> global_object( |
4158 JSObject::cast(native_context()->global_object())); | 4156 JSObject::cast(native_context()->global_object())); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4272 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR); | 4270 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR); |
4273 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); | 4271 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); |
4274 if (it.IsFound()) continue; | 4272 if (it.IsFound()) continue; |
4275 // Set the property. | 4273 // Set the property. |
4276 DCHECK(properties->ValueAt(key_index)->IsPropertyCell()); | 4274 DCHECK(properties->ValueAt(key_index)->IsPropertyCell()); |
4277 Handle<PropertyCell> cell( | 4275 Handle<PropertyCell> cell( |
4278 PropertyCell::cast(properties->ValueAt(key_index)), isolate()); | 4276 PropertyCell::cast(properties->ValueAt(key_index)), isolate()); |
4279 Handle<Object> value(cell->value(), isolate()); | 4277 Handle<Object> value(cell->value(), isolate()); |
4280 if (value->IsTheHole(isolate())) continue; | 4278 if (value->IsTheHole(isolate())) continue; |
4281 PropertyDetails details = cell->property_details(); | 4279 PropertyDetails details = cell->property_details(); |
4282 DCHECK_EQ(kData, details.kind()); | 4280 if (details.kind() != kData) continue; |
4283 JSObject::AddProperty(to, key, value, details.attributes()); | 4281 JSObject::AddProperty(to, key, value, details.attributes()); |
4284 } | 4282 } |
4285 } else { | 4283 } else { |
4286 // Copy all keys and values in enumeration order. | 4284 // Copy all keys and values in enumeration order. |
4287 Handle<NameDictionary> properties = | 4285 Handle<NameDictionary> properties = |
4288 Handle<NameDictionary>(from->property_dictionary()); | 4286 Handle<NameDictionary>(from->property_dictionary()); |
4289 Handle<FixedArray> key_indices = | 4287 Handle<FixedArray> key_indices = |
4290 NameDictionary::IterationIndices(properties); | 4288 NameDictionary::IterationIndices(properties); |
4291 for (int i = 0; i < key_indices->length(); i++) { | 4289 for (int i = 0; i < key_indices->length(); i++) { |
4292 int key_index = Smi::cast(key_indices->get(i))->value(); | 4290 int key_index = Smi::cast(key_indices->get(i))->value(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4370 } | 4368 } |
4371 | 4369 |
4372 private: | 4370 private: |
4373 bool flag_; | 4371 bool flag_; |
4374 bool enabled_; | 4372 bool enabled_; |
4375 }; | 4373 }; |
4376 | 4374 |
4377 Genesis::Genesis(Isolate* isolate, | 4375 Genesis::Genesis(Isolate* isolate, |
4378 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 4376 MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
4379 v8::Local<v8::ObjectTemplate> global_proxy_template, | 4377 v8::Local<v8::ObjectTemplate> global_proxy_template, |
4380 v8::ExtensionConfiguration* extensions, | |
4381 size_t context_snapshot_index, GlobalContextType context_type) | 4378 size_t context_snapshot_index, GlobalContextType context_type) |
4382 : isolate_(isolate), active_(isolate->bootstrapper()) { | 4379 : isolate_(isolate), active_(isolate->bootstrapper()) { |
4383 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); | 4380 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); |
4384 result_ = Handle<Context>::null(); | 4381 result_ = Handle<Context>::null(); |
4385 global_proxy_ = Handle<JSGlobalProxy>::null(); | 4382 global_proxy_ = Handle<JSGlobalProxy>::null(); |
| 4383 bool create_new_global_proxy = context_snapshot_index == 0; |
4386 | 4384 |
4387 // Before creating the roots we must save the context and restore it | 4385 // Before creating the roots we must save the context and restore it |
4388 // on all function exits. | 4386 // on all function exits. |
4389 SaveContext saved_context(isolate); | 4387 SaveContext saved_context(isolate); |
4390 | 4388 |
4391 // During genesis, the boilerplate for stack overflow won't work until the | 4389 // During genesis, the boilerplate for stack overflow won't work until the |
4392 // environment has been at least partially initialized. Add a stack check | 4390 // environment has been at least partially initialized. Add a stack check |
4393 // before entering JS code to catch overflow early. | 4391 // before entering JS code to catch overflow early. |
4394 StackLimitCheck check(isolate); | 4392 StackLimitCheck check(isolate); |
4395 if (check.HasOverflowed()) { | 4393 if (check.HasOverflowed()) { |
4396 isolate->StackOverflow(); | 4394 isolate->StackOverflow(); |
4397 return; | 4395 return; |
4398 } | 4396 } |
4399 | 4397 |
4400 // The deserializer needs to hook up references to the global proxy. | 4398 // The deserializer needs to hook up references to the global proxy. |
4401 // Create an uninitialized global proxy now if we don't have one | 4399 // Create an uninitialized global proxy now if we don't have one |
4402 // and initialize it later in CreateNewGlobals. | 4400 // and initialize it later in CreateNewGlobals. |
4403 Handle<JSGlobalProxy> global_proxy; | 4401 Handle<JSGlobalProxy> global_proxy; |
4404 if (!maybe_global_proxy.ToHandle(&global_proxy)) { | 4402 if (!maybe_global_proxy.ToHandle(&global_proxy) && create_new_global_proxy) { |
4405 const int internal_field_count = | 4403 const int internal_field_count = |
4406 !global_proxy_template.IsEmpty() | 4404 !global_proxy_template.IsEmpty() |
4407 ? global_proxy_template->InternalFieldCount() | 4405 ? global_proxy_template->InternalFieldCount() |
4408 : 0; | 4406 : 0; |
4409 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy( | 4407 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy( |
4410 JSGlobalProxy::SizeWithInternalFields(internal_field_count)); | 4408 JSGlobalProxy::SizeWithInternalFields(internal_field_count)); |
4411 } | 4409 } |
4412 | 4410 |
4413 // We can only de-serialize a context if the isolate was initialized from | 4411 // We can only de-serialize a context if the isolate was initialized from |
4414 // a snapshot. Otherwise we have to build the context from scratch. | 4412 // a snapshot. Otherwise we have to build the context from scratch. |
(...skipping 11 matching lines...) Expand all Loading... |
4426 isolate->counters()->contexts_created_by_snapshot()->Increment(); | 4424 isolate->counters()->contexts_created_by_snapshot()->Increment(); |
4427 #if TRACE_MAPS | 4425 #if TRACE_MAPS |
4428 if (FLAG_trace_maps) { | 4426 if (FLAG_trace_maps) { |
4429 Handle<JSFunction> object_fun = isolate->object_function(); | 4427 Handle<JSFunction> object_fun = isolate->object_function(); |
4430 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n", | 4428 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n", |
4431 reinterpret_cast<void*>(object_fun->initial_map()), | 4429 reinterpret_cast<void*>(object_fun->initial_map()), |
4432 object_fun->shared()->unique_id()); | 4430 object_fun->shared()->unique_id()); |
4433 Map::TraceAllTransitions(object_fun->initial_map()); | 4431 Map::TraceAllTransitions(object_fun->initial_map()); |
4434 } | 4432 } |
4435 #endif | 4433 #endif |
4436 Handle<JSGlobalObject> global_object = | |
4437 CreateNewGlobals(global_proxy_template, global_proxy); | |
4438 | 4434 |
4439 HookUpGlobalProxy(global_object, global_proxy); | 4435 if (create_new_global_proxy) { |
4440 HookUpGlobalObject(global_object); | 4436 Handle<JSGlobalObject> global_object = |
| 4437 CreateNewGlobals(global_proxy_template, global_proxy); |
4441 | 4438 |
4442 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 4439 HookUpGlobalProxy(global_object, global_proxy); |
| 4440 HookUpGlobalObject(global_object); |
| 4441 |
| 4442 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
| 4443 } |
4443 } else { | 4444 } else { |
4444 // We get here if there was no context snapshot. | 4445 // We get here if there was no context snapshot. |
4445 CreateRoots(); | 4446 CreateRoots(); |
4446 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); | 4447 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); |
4447 CreateStrictModeFunctionMaps(empty_function); | 4448 CreateStrictModeFunctionMaps(empty_function); |
4448 CreateIteratorMaps(empty_function); | 4449 CreateIteratorMaps(empty_function); |
4449 CreateAsyncFunctionMaps(empty_function); | 4450 CreateAsyncFunctionMaps(empty_function); |
4450 Handle<JSGlobalObject> global_object = | 4451 Handle<JSGlobalObject> global_object = |
4451 CreateNewGlobals(global_proxy_template, global_proxy); | 4452 CreateNewGlobals(global_proxy_template, global_proxy); |
4452 HookUpGlobalProxy(global_object, global_proxy); | 4453 HookUpGlobalProxy(global_object, global_proxy); |
4453 InitializeGlobal(global_object, empty_function, context_type); | 4454 InitializeGlobal(global_object, empty_function, context_type); |
4454 InitializeNormalizedMapCaches(); | 4455 InitializeNormalizedMapCaches(); |
4455 | 4456 |
4456 if (!InstallNatives(context_type)) return; | 4457 if (!InstallNatives(context_type)) return; |
4457 | 4458 |
4458 MakeFunctionInstancePrototypeWritable(); | 4459 MakeFunctionInstancePrototypeWritable(); |
4459 | 4460 |
4460 if (!InstallExtraNatives()) return; | 4461 if (!InstallExtraNatives()) return; |
4461 if (!ConfigureGlobalObjects(global_proxy_template)) return; | 4462 if (!ConfigureGlobalObjects(global_proxy_template)) return; |
4462 | 4463 |
4463 isolate->counters()->contexts_created_from_scratch()->Increment(); | 4464 isolate->counters()->contexts_created_from_scratch()->Increment(); |
4464 // Re-initialize the counter because it got incremented during snapshot | |
4465 // creation. | |
4466 isolate->native_context()->set_errors_thrown(Smi::kZero); | |
4467 } | 4465 } |
4468 | 4466 |
4469 // Install experimental natives. Do not include them into the | 4467 // Install experimental natives. Do not include them into the |
4470 // snapshot as we should be able to turn them off at runtime. Re-installing | 4468 // snapshot as we should be able to turn them off at runtime. Re-installing |
4471 // them after they have already been deserialized would also fail. | 4469 // them after they have already been deserialized would also fail. |
4472 if (context_type == FULL_CONTEXT) { | 4470 if (context_type == FULL_CONTEXT) { |
4473 if (!isolate->serializer_enabled()) { | 4471 if (!isolate->serializer_enabled()) { |
4474 InitializeExperimentalGlobal(); | 4472 InitializeExperimentalGlobal(); |
4475 if (!InstallExperimentalNatives()) return; | 4473 if (!InstallExperimentalNatives()) return; |
4476 | 4474 |
4477 if (FLAG_experimental_extras) { | 4475 if (FLAG_experimental_extras) { |
4478 if (!InstallExperimentalExtraNatives()) return; | 4476 if (!InstallExperimentalExtraNatives()) return; |
4479 } | 4477 } |
4480 } | 4478 } |
4481 // The serializer cannot serialize typed arrays. Reset those typed arrays | 4479 // The serializer cannot serialize typed arrays. Reset those typed arrays |
4482 // for each new context. | 4480 // for each new context. |
4483 } else if (context_type == DEBUG_CONTEXT) { | 4481 } else if (context_type == DEBUG_CONTEXT) { |
4484 DCHECK(!isolate->serializer_enabled()); | 4482 DCHECK(!isolate->serializer_enabled()); |
4485 InitializeExperimentalGlobal(); | 4483 InitializeExperimentalGlobal(); |
4486 if (!InstallDebuggerNatives()) return; | 4484 if (!InstallDebuggerNatives()) return; |
4487 } | 4485 } |
4488 | 4486 |
4489 ConfigureUtilsObject(context_type); | 4487 ConfigureUtilsObject(context_type); |
4490 | 4488 |
4491 // Check that the script context table is empty except for the 'this' binding. | 4489 // Check that the script context table is empty except for the 'this' binding. |
4492 // We do not need script contexts for native scripts. | 4490 // We do not need script contexts for native scripts. |
4493 DCHECK_EQ(1, native_context()->script_context_table()->used()); | 4491 DCHECK_EQ(1, native_context()->script_context_table()->used()); |
4494 | 4492 |
| 4493 native_context()->ResetErrorsThrown(); |
4495 result_ = native_context(); | 4494 result_ = native_context(); |
4496 } | 4495 } |
4497 | 4496 |
4498 Genesis::Genesis(Isolate* isolate, | 4497 Genesis::Genesis(Isolate* isolate, |
4499 MaybeHandle<JSGlobalProxy> maybe_global_proxy, | 4498 MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
4500 v8::Local<v8::ObjectTemplate> global_proxy_template) | 4499 v8::Local<v8::ObjectTemplate> global_proxy_template) |
4501 : isolate_(isolate), active_(isolate->bootstrapper()) { | 4500 : isolate_(isolate), active_(isolate->bootstrapper()) { |
4502 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); | 4501 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); |
4503 result_ = Handle<Context>::null(); | 4502 result_ = Handle<Context>::null(); |
4504 global_proxy_ = Handle<JSGlobalProxy>::null(); | 4503 global_proxy_ = Handle<JSGlobalProxy>::null(); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4584 } | 4583 } |
4585 | 4584 |
4586 | 4585 |
4587 // Called when the top-level V8 mutex is destroyed. | 4586 // Called when the top-level V8 mutex is destroyed. |
4588 void Bootstrapper::FreeThreadResources() { | 4587 void Bootstrapper::FreeThreadResources() { |
4589 DCHECK(!IsActive()); | 4588 DCHECK(!IsActive()); |
4590 } | 4589 } |
4591 | 4590 |
4592 } // namespace internal | 4591 } // namespace internal |
4593 } // namespace v8 | 4592 } // namespace v8 |
OLD | NEW |