| Index: src/bootstrapper.cc
|
| diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
|
| index 983da4787fe5a3064b3369e7e8f550544c8beeea..773ae7ed535b908224647ebb5e5f44497f04f0cb 100644
|
| --- a/src/bootstrapper.cc
|
| +++ b/src/bootstrapper.cc
|
| @@ -48,6 +48,12 @@ FixedArray* GetCache<ExtraNatives>(Heap* heap) {
|
| }
|
|
|
|
|
| +template <>
|
| +FixedArray* GetCache<CodeStubNatives>(Heap* heap) {
|
| + return heap->code_stub_natives_source_cache();
|
| +}
|
| +
|
| +
|
| template <class Source>
|
| Handle<String> Bootstrapper::SourceLookup(int index) {
|
| DCHECK(0 <= index && index < Source::GetBuiltinsCount());
|
| @@ -74,6 +80,7 @@ template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
|
| template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
|
| int index);
|
| template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
|
| +template Handle<String> Bootstrapper::SourceLookup<CodeStubNatives>(int index);
|
|
|
|
|
| void Bootstrapper::Initialize(bool create_heap_objects) {
|
| @@ -142,6 +149,7 @@ void Bootstrapper::TearDown() {
|
| DeleteNativeSources(isolate_->heap()->natives_source_cache());
|
| DeleteNativeSources(isolate_->heap()->experimental_natives_source_cache());
|
| DeleteNativeSources(isolate_->heap()->extra_natives_source_cache());
|
| + DeleteNativeSources(isolate_->heap()->code_stub_natives_source_cache());
|
| extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical
|
| }
|
|
|
| @@ -150,7 +158,7 @@ class Genesis BASE_EMBEDDED {
|
| public:
|
| Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
| v8::Local<v8::ObjectTemplate> global_proxy_template,
|
| - v8::ExtensionConfiguration* extensions);
|
| + v8::ExtensionConfiguration* extensions, ContextType context_type);
|
| ~Genesis() { }
|
|
|
| Isolate* isolate() const { return isolate_; }
|
| @@ -203,7 +211,8 @@ class Genesis BASE_EMBEDDED {
|
| void HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts);
|
| // New context initialization. Used for creating a context from scratch.
|
| void InitializeGlobal(Handle<GlobalObject> global_object,
|
| - Handle<JSFunction> empty_function);
|
| + Handle<JSFunction> empty_function,
|
| + ContextType context_type);
|
| void InitializeExperimentalGlobal();
|
| // Installs the contents of the native .js files on the global objects.
|
| // Used for creating a context from scratch.
|
| @@ -224,7 +233,7 @@ class Genesis BASE_EMBEDDED {
|
| Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
|
| const char* name,
|
| ElementsKind elements_kind);
|
| - bool InstallNatives();
|
| + bool InstallNatives(ContextType context_type);
|
|
|
| void InstallTypedArray(
|
| const char* name,
|
| @@ -350,18 +359,39 @@ void Bootstrapper::Iterate(ObjectVisitor* v) {
|
| Handle<Context> Bootstrapper::CreateEnvironment(
|
| MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
| v8::Local<v8::ObjectTemplate> global_proxy_template,
|
| - v8::ExtensionConfiguration* extensions) {
|
| + v8::ExtensionConfiguration* extensions, ContextType context_type) {
|
| HandleScope scope(isolate_);
|
| - Genesis genesis(
|
| - isolate_, maybe_global_proxy, global_proxy_template, extensions);
|
| + Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
|
| + extensions, context_type);
|
| Handle<Context> env = genesis.result();
|
| - if (env.is_null() || !InstallExtensions(env, extensions)) {
|
| + if (env.is_null() ||
|
| + (context_type == FULL_CONTEXT && !InstallExtensions(env, extensions))) {
|
| return Handle<Context>();
|
| }
|
| return scope.CloseAndEscape(env);
|
| }
|
|
|
|
|
| +bool Bootstrapper::CreateCodeStubContext(Isolate* isolate) {
|
| + HandleScope scope(isolate);
|
| + SaveContext save_context(isolate);
|
| + BootstrapperActive active(this);
|
| +
|
| + v8::ExtensionConfiguration no_extensions;
|
| + Handle<Context> native_context = CreateEnvironment(
|
| + MaybeHandle<JSGlobalProxy>(), v8::Local<v8::ObjectTemplate>(),
|
| + &no_extensions, THIN_CONTEXT);
|
| + isolate->heap()->set_code_stub_context(*native_context);
|
| + isolate->set_context(*native_context);
|
| + Handle<JSObject> code_stub_exports =
|
| + isolate->factory()->NewJSObject(isolate->object_function());
|
| + JSObject::NormalizeProperties(code_stub_exports, CLEAR_INOBJECT_PROPERTIES, 2,
|
| + "container to export to extra natives");
|
| + isolate->heap()->set_code_stub_exports_object(*code_stub_exports);
|
| + return InstallCodeStubNatives(isolate);
|
| +}
|
| +
|
| +
|
| static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
|
| // object.__proto__ = proto;
|
| Handle<Map> old_map = Handle<Map>(object->map());
|
| @@ -992,7 +1022,8 @@ void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object,
|
| // This is only called if we are not using snapshots. The equivalent
|
| // work in the snapshot case is done in HookUpGlobalObject.
|
| void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
|
| - Handle<JSFunction> empty_function) {
|
| + Handle<JSFunction> empty_function,
|
| + ContextType context_type) {
|
| // --- N a t i v e C o n t e x t ---
|
| // Use the empty function as closure (no scope info).
|
| native_context()->set_closure(*empty_function);
|
| @@ -1217,6 +1248,12 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
|
| JSRegExp::Flags(0), 0);
|
| }
|
|
|
| + // Initialize the embedder data slot.
|
| + Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
|
| + native_context()->set_embedder_data(*embedder_data);
|
| +
|
| + if (context_type == THIN_CONTEXT) return;
|
| +
|
| { // -- J S O N
|
| Handle<String> name = factory->InternalizeUtf8String("JSON");
|
| Handle<JSFunction> cons = factory->NewFunction(name);
|
| @@ -1462,10 +1499,6 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
|
| native_context()->set_call_as_constructor_delegate(*delegate);
|
| delegate->shared()->DontAdaptArguments();
|
| }
|
| -
|
| - // Initialize the embedder data slot.
|
| - Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
|
| - native_context()->set_embedder_data(*embedder_data);
|
| }
|
|
|
|
|
| @@ -1502,18 +1535,21 @@ void Genesis::InitializeExperimentalGlobal() {
|
| }
|
|
|
|
|
| -bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
|
| +bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
|
| Vector<const char> name = Natives::GetScriptName(index);
|
| Handle<String> source_code =
|
| isolate->bootstrapper()->SourceLookup<Natives>(index);
|
| Handle<Object> global = isolate->global_object();
|
| Handle<Object> utils = isolate->natives_utils_object();
|
| Handle<Object> args[] = {global, utils};
|
| - return CompileNative(isolate, name, source_code, arraysize(args), args);
|
| +
|
| + return Bootstrapper::CompileNative(
|
| + isolate, name, Handle<JSObject>(isolate->native_context()->builtins()),
|
| + source_code, arraysize(args), args);
|
| }
|
|
|
|
|
| -bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
|
| +bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
|
| HandleScope scope(isolate);
|
| Vector<const char> name = ExperimentalNatives::GetScriptName(index);
|
| Handle<String> source_code =
|
| @@ -1521,11 +1557,13 @@ bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
|
| Handle<Object> global = isolate->global_object();
|
| Handle<Object> utils = isolate->natives_utils_object();
|
| Handle<Object> args[] = {global, utils};
|
| - return CompileNative(isolate, name, source_code, arraysize(args), args);
|
| + return Bootstrapper::CompileNative(
|
| + isolate, name, Handle<JSObject>(isolate->native_context()->builtins()),
|
| + source_code, arraysize(args), args);
|
| }
|
|
|
|
|
| -bool Genesis::CompileExtraBuiltin(Isolate* isolate, int index) {
|
| +bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
|
| HandleScope scope(isolate);
|
| Vector<const char> name = ExtraNatives::GetScriptName(index);
|
| Handle<String> source_code =
|
| @@ -1533,13 +1571,30 @@ bool Genesis::CompileExtraBuiltin(Isolate* isolate, int index) {
|
| Handle<Object> global = isolate->global_object();
|
| Handle<Object> exports = isolate->extras_exports_object();
|
| Handle<Object> args[] = {global, exports};
|
| - return CompileNative(isolate, name, source_code, arraysize(args), args);
|
| + return Bootstrapper::CompileNative(
|
| + isolate, name, Handle<JSObject>(isolate->native_context()->builtins()),
|
| + source_code, arraysize(args), args);
|
| }
|
|
|
|
|
| -bool Genesis::CompileNative(Isolate* isolate, Vector<const char> name,
|
| - Handle<String> source, int argc,
|
| - Handle<Object> argv[]) {
|
| +bool Bootstrapper::CompileCodeStubBuiltin(Isolate* isolate, int index) {
|
| + HandleScope scope(isolate);
|
| + Vector<const char> name = CodeStubNatives::GetScriptName(index);
|
| + Handle<String> source_code =
|
| + isolate->bootstrapper()->SourceLookup<CodeStubNatives>(index);
|
| + Handle<JSObject> global(isolate->global_object());
|
| + Handle<JSObject> exports(isolate->heap()->code_stub_exports_object());
|
| + Handle<Object> args[] = {global, exports};
|
| + bool result =
|
| + CompileNative(isolate, name, global, source_code, arraysize(args), args);
|
| + return result;
|
| +}
|
| +
|
| +
|
| +bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
|
| + Handle<JSObject> receiver,
|
| + Handle<String> source, int argc,
|
| + Handle<Object> argv[]) {
|
| SuppressDebug compiling_natives(isolate->debug());
|
| // During genesis, the boilerplate for stack overflow won't work until the
|
| // environment has been at least partially initialized. Add a stack check
|
| @@ -1563,7 +1618,6 @@ bool Genesis::CompileNative(Isolate* isolate, Vector<const char> name,
|
| DCHECK(context->IsNativeContext());
|
|
|
| Handle<Context> runtime_context(context->runtime_context());
|
| - Handle<JSBuiltinsObject> receiver(context->builtins());
|
| Handle<JSFunction> fun =
|
| isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
|
| runtime_context);
|
| @@ -1969,7 +2023,7 @@ Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
|
| }
|
|
|
|
|
| -bool Genesis::InstallNatives() {
|
| +bool Genesis::InstallNatives(ContextType context_type) {
|
| HandleScope scope(isolate());
|
|
|
| // Create a function for the builtins object. Allocate space for the
|
| @@ -2017,6 +2071,14 @@ bool Genesis::InstallNatives() {
|
|
|
| native_context()->set_runtime_context(*context);
|
|
|
| + if (context_type == THIN_CONTEXT) {
|
| + int js_builtins_script_index = Natives::GetDebuggerCount();
|
| + if (!Bootstrapper::CompileBuiltin(isolate(), js_builtins_script_index))
|
| + return false;
|
| + if (!InstallJSBuiltins(builtins)) return false;
|
| + return true;
|
| + }
|
| +
|
| // Set up the utils object as shared container between native scripts.
|
| Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
|
| JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
|
| @@ -2315,11 +2377,12 @@ bool Genesis::InstallNatives() {
|
| }
|
|
|
| int i = Natives::GetDebuggerCount();
|
| - if (!CompileBuiltin(isolate(), i)) return false;
|
| + if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
|
| +
|
| if (!InstallJSBuiltins(builtins)) return false;
|
|
|
| for (++i; i < Natives::GetBuiltinsCount(); ++i) {
|
| - if (!CompileBuiltin(isolate(), i)) return false;
|
| + if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
|
| }
|
|
|
| if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
|
| @@ -2509,7 +2572,9 @@ bool Genesis::InstallExperimentalNatives() {
|
| Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
|
| if (strncmp(script_name.start(), id##_natives[j], \
|
| script_name.length()) == 0) { \
|
| - if (!CompileExperimentalBuiltin(isolate(), i)) return false; \
|
| + if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) { \
|
| + return false; \
|
| + } \
|
| } \
|
| } \
|
| }
|
| @@ -2530,7 +2595,17 @@ bool Genesis::InstallExperimentalNatives() {
|
| bool Genesis::InstallExtraNatives() {
|
| for (int i = ExtraNatives::GetDebuggerCount();
|
| i < ExtraNatives::GetBuiltinsCount(); i++) {
|
| - if (!CompileExtraBuiltin(isolate(), i)) return false;
|
| + if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +
|
| +bool Bootstrapper::InstallCodeStubNatives(Isolate* isolate) {
|
| + for (int i = CodeStubNatives::GetDebuggerCount();
|
| + i < CodeStubNatives::GetBuiltinsCount(); i++) {
|
| + if (!CompileCodeStubBuiltin(isolate, i)) return false;
|
| }
|
|
|
| return true;
|
| @@ -3079,7 +3154,8 @@ class NoTrackDoubleFieldsForSerializerScope {
|
| Genesis::Genesis(Isolate* isolate,
|
| MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
| v8::Local<v8::ObjectTemplate> global_proxy_template,
|
| - v8::ExtensionConfiguration* extensions)
|
| + v8::ExtensionConfiguration* extensions,
|
| + ContextType context_type)
|
| : isolate_(isolate), active_(isolate->bootstrapper()) {
|
| NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
|
| result_ = Handle<Context>::null();
|
| @@ -3147,29 +3223,34 @@ Genesis::Genesis(Isolate* isolate,
|
| Handle<GlobalObject> global_object =
|
| CreateNewGlobals(global_proxy_template, global_proxy);
|
| HookUpGlobalProxy(global_object, global_proxy);
|
| - InitializeGlobal(global_object, empty_function);
|
| + InitializeGlobal(global_object, empty_function, context_type);
|
| InstallJSFunctionResultCaches();
|
| InitializeNormalizedMapCaches();
|
| - if (!InstallNatives()) return;
|
| +
|
| + if (!InstallNatives(context_type)) return;
|
|
|
| MakeFunctionInstancePrototypeWritable();
|
|
|
| - if (!ConfigureGlobalObjects(global_proxy_template)) return;
|
| + if (context_type == FULL_CONTEXT) {
|
| + if (!ConfigureGlobalObjects(global_proxy_template)) return;
|
| + }
|
| isolate->counters()->contexts_created_from_scratch()->Increment();
|
| }
|
|
|
| // Install experimental and extra natives. Do not include them into the
|
| // snapshot as we should be able to turn them off at runtime. Re-installing
|
| // them after they have already been deserialized would also fail.
|
| - if (!isolate->serializer_enabled()) {
|
| - InitializeExperimentalGlobal();
|
| - if (!InstallExperimentalNatives()) return;
|
| - if (!InstallExtraNatives()) return;
|
| - }
|
| + if (context_type == FULL_CONTEXT) {
|
| + if (!isolate->serializer_enabled()) {
|
| + InitializeExperimentalGlobal();
|
| + if (!InstallExperimentalNatives()) return;
|
| + if (!InstallExtraNatives()) return;
|
| + }
|
|
|
| - // The serializer cannot serialize typed arrays. Reset those typed arrays
|
| - // for each new context.
|
| - InitializeBuiltinTypedArrays();
|
| + // The serializer cannot serialize typed arrays. Reset those typed arrays
|
| + // for each new context.
|
| + InitializeBuiltinTypedArrays();
|
| + }
|
|
|
| result_ = native_context();
|
| }
|
|
|