Index: src/bootstrapper.cc |
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc |
index 7d23fe5af01951901f154b1a5d330d84af9afb32..f3dd682871b74964a4afd0860aed1381c49c1944 100644 |
--- a/src/bootstrapper.cc |
+++ b/src/bootstrapper.cc |
@@ -217,7 +217,7 @@ |
HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION) |
#undef DECLARE_FEATURE_INITIALIZATION |
- Handle<JSFunction> InstallInternalArray(Handle<JSObject> target, |
+ Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins, |
const char* name, |
ElementsKind elements_kind); |
bool InstallNatives(); |
@@ -232,8 +232,6 @@ |
void InstallBuiltinFunctionIds(); |
void InstallJSFunctionResultCaches(); |
void InitializeNormalizedMapCaches(); |
- |
- void RemoveExportObjects(); |
enum ExtensionTraversalState { |
UNVISITED, VISITED, INSTALLED |
@@ -309,15 +307,19 @@ |
FunctionMode function_mode); |
void SetStrongFunctionInstanceDescriptor(Handle<Map> map); |
- static bool CompileBuiltin(Isolate* isolate, int index, |
- Handle<JSObject> shared); |
+ static bool CompileBuiltin(Isolate* isolate, int index); |
static bool CompileExperimentalBuiltin(Isolate* isolate, int index); |
static bool CompileExtraBuiltin(Isolate* isolate, int index); |
- static bool CompileNative(Isolate* isolate, Vector<const char> name, |
- Handle<String> source, int argc, |
- Handle<Object> argv[]); |
- |
- static bool CompileExtension(Isolate* isolate, v8::Extension* extension); |
+ static bool CompileNative(Isolate* isolate, |
+ Vector<const char> name, |
+ Handle<String> source); |
+ static bool CompileScriptCached(Isolate* isolate, |
+ Vector<const char> name, |
+ Handle<String> source, |
+ SourceCodeCache* cache, |
+ v8::Extension* extension, |
+ Handle<Context> top_context, |
+ bool use_runtime_context); |
Isolate* isolate_; |
Handle<Context> result_; |
@@ -1439,45 +1441,34 @@ |
} |
-bool Genesis::CompileBuiltin(Isolate* isolate, int index, |
- Handle<JSObject> shared) { |
+bool Genesis::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> exports = isolate->builtin_exports_object(); |
- Handle<Object> args[] = {global, shared, exports}; |
- return CompileNative(isolate, name, source_code, arraysize(args), args); |
+ return CompileNative(isolate, name, source_code); |
} |
bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) { |
- HandleScope scope(isolate); |
Vector<const char> name = ExperimentalNatives::GetScriptName(index); |
Handle<String> source_code = |
isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index); |
- Handle<Object> global = isolate->global_object(); |
- Handle<Object> exports = isolate->builtin_exports_object(); |
- Handle<Object> args[] = {global, exports}; |
- return CompileNative(isolate, name, source_code, arraysize(args), args); |
+ return CompileNative(isolate, name, source_code); |
} |
bool Genesis::CompileExtraBuiltin(Isolate* isolate, int index) { |
- HandleScope scope(isolate); |
Vector<const char> name = ExtraNatives::GetScriptName(index); |
Handle<String> source_code = |
isolate->bootstrapper()->SourceLookup<ExtraNatives>(index); |
- Handle<Object> global = isolate->global_object(); |
- Handle<Object> exports = isolate->builtin_exports_object(); |
- Handle<Object> args[] = {global, exports}; |
- return CompileNative(isolate, name, source_code, arraysize(args), args); |
-} |
- |
- |
-bool Genesis::CompileNative(Isolate* isolate, Vector<const char> name, |
- Handle<String> source, int argc, |
- Handle<Object> argv[]) { |
+ return CompileNative(isolate, name, source_code); |
+} |
+ |
+ |
+bool Genesis::CompileNative(Isolate* isolate, |
+ Vector<const char> name, |
+ Handle<String> source) { |
+ HandleScope scope(isolate); |
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 |
@@ -1485,72 +1476,78 @@ |
StackLimitCheck check(isolate); |
if (check.HasOverflowed()) return false; |
- Handle<Context> context(isolate->context()); |
- |
- Handle<String> script_name = |
- isolate->factory()->NewStringFromUtf8(name).ToHandleChecked(); |
- Handle<SharedFunctionInfo> function_info = Compiler::CompileScript( |
- source, script_name, 0, 0, false, false, Handle<Object>(), context, NULL, |
- NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE, false); |
- |
- 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); |
- |
- // For non-extension scripts, run script to get the function wrapper. |
- Handle<Object> wrapper; |
- if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) { |
- return false; |
- } |
- // Then run the function wrapper. |
- return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver, |
- argc, argv).is_null(); |
-} |
- |
- |
-bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) { |
+ bool result = CompileScriptCached(isolate, |
+ name, |
+ source, |
+ NULL, |
+ NULL, |
+ Handle<Context>(isolate->context()), |
+ true); |
+ DCHECK(isolate->has_pending_exception() != result); |
+ if (!result) isolate->clear_pending_exception(); |
+ return result; |
+} |
+ |
+ |
+bool Genesis::CompileScriptCached(Isolate* isolate, |
+ Vector<const char> name, |
+ Handle<String> source, |
+ SourceCodeCache* cache, |
+ v8::Extension* extension, |
+ Handle<Context> top_context, |
+ bool use_runtime_context) { |
Factory* factory = isolate->factory(); |
HandleScope scope(isolate); |
Handle<SharedFunctionInfo> function_info; |
- Handle<String> source = |
- isolate->factory() |
- ->NewExternalStringFromOneByte(extension->source()) |
- .ToHandleChecked(); |
- DCHECK(source->IsOneByteRepresentation()); |
- |
// If we can't find the function in the cache, we compile a new |
// function and insert it into the cache. |
- Vector<const char> name = CStrVector(extension->name()); |
- SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache(); |
- Handle<Context> context(isolate->context()); |
- DCHECK(context->IsNativeContext()); |
- |
- if (!cache->Lookup(name, &function_info)) { |
+ if (cache == NULL || !cache->Lookup(name, &function_info)) { |
+ DCHECK(source->IsOneByteRepresentation()); |
Handle<String> script_name = |
factory->NewStringFromUtf8(name).ToHandleChecked(); |
function_info = Compiler::CompileScript( |
- source, script_name, 0, 0, false, false, Handle<Object>(), context, |
- extension, NULL, ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, |
- false); |
+ source, script_name, 0, 0, false, false, Handle<Object>(), top_context, |
+ extension, NULL, ScriptCompiler::kNoCompileOptions, |
+ use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE, false); |
if (function_info.is_null()) return false; |
- cache->Add(name, function_info); |
+ if (cache != NULL) cache->Add(name, function_info); |
} |
// Set up the function context. Conceptually, we should clone the |
// function before overwriting the context but since we're in a |
// single-threaded environment it is not strictly necessary. |
+ DCHECK(top_context->IsNativeContext()); |
+ Handle<Context> context = |
+ Handle<Context>(use_runtime_context |
+ ? Handle<Context>(top_context->runtime_context()) |
+ : top_context); |
Handle<JSFunction> fun = |
factory->NewFunctionFromSharedFunctionInfo(function_info, context); |
// Call function using either the runtime object or the global |
// object as the receiver. Provide no parameters. |
- Handle<Object> receiver = isolate->global_object(); |
- return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null(); |
+ Handle<Object> receiver = |
+ Handle<Object>(use_runtime_context |
+ ? top_context->builtins() |
+ : top_context->global_object(), |
+ isolate); |
+ MaybeHandle<Object> result; |
+ if (extension == NULL) { |
+ // For non-extension scripts, run script to get the function wrapper. |
+ Handle<Object> wrapper; |
+ if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) { |
+ return false; |
+ } |
+ // Then run the function wrapper. |
+ Handle<Object> global_obj(top_context->global_object(), isolate); |
+ Handle<Object> args[] = {global_obj}; |
+ result = Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), |
+ receiver, arraysize(args), args); |
+ } else { |
+ result = Execution::Call(isolate, fun, receiver, 0, NULL); |
+ } |
+ return !result.is_null(); |
} |
@@ -1821,9 +1818,10 @@ |
} |
-Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target, |
- const char* name, |
- ElementsKind elements_kind) { |
+Handle<JSFunction> Genesis::InstallInternalArray( |
+ Handle<JSBuiltinsObject> builtins, |
+ const char* name, |
+ ElementsKind elements_kind) { |
// --- I n t e r n a l A r r a y --- |
// An array constructor on the builtins object that works like |
// the public Array constructor, except that its prototype |
@@ -1832,9 +1830,9 @@ |
// must not be leaked to user code. |
Handle<JSObject> prototype = |
factory()->NewJSObject(isolate()->object_function(), TENURED); |
- Handle<JSFunction> array_function = |
- InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype, |
- Builtins::kInternalArrayCode); |
+ Handle<JSFunction> array_function = InstallFunction( |
+ builtins, name, JS_ARRAY_TYPE, JSArray::kSize, |
+ prototype, Builtins::kInternalArrayCode); |
InternalArrayConstructorStub internal_array_constructor_stub(isolate()); |
Handle<Code> code = internal_array_constructor_stub.GetCode(); |
@@ -1911,27 +1909,6 @@ |
context->set_global_object(*builtins); // override builtins global object |
native_context()->set_runtime_context(*context); |
- |
- // Set up shared object to set up cross references between native scripts. |
- // "shared" is used for cross references between native scripts that are part |
- // of the snapshot. "builtin_exports" is used for experimental natives. |
- Handle<JSObject> shared = |
- factory()->NewJSObject(isolate()->object_function()); |
- JSObject::NormalizeProperties(shared, CLEAR_INOBJECT_PROPERTIES, 16, |
- "container to share between native scripts"); |
- Handle<JSObject> builtin_exports = |
- factory()->NewJSObject(isolate()->object_function()); |
- JSObject::NormalizeProperties(builtin_exports, CLEAR_INOBJECT_PROPERTIES, 16, |
- "container to export to experimental natives"); |
- native_context()->set_builtin_exports_object(*builtin_exports); |
- |
- if (FLAG_expose_natives_as != nullptr) { |
- Handle<String> shared_key = factory()->NewStringFromAsciiChecked("shared"); |
- Handle<String> builtin_exports_key = |
- factory()->NewStringFromAsciiChecked("builtin_exports"); |
- JSObject::AddProperty(builtins, shared_key, shared, NONE); |
- JSObject::AddProperty(builtins, builtin_exports_key, builtin_exports, NONE); |
- } |
{ // -- S c r i p t |
// Builtin functions for Script. |
@@ -2105,13 +2082,13 @@ |
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT |
// transition easy to trap. Moreover, they rarely are smi-only. |
{ |
- HandleScope scope(isolate()); |
- Handle<JSObject> builtin_exports = |
- Handle<JSObject>::cast(isolate()->builtin_exports_object()); |
- Handle<JSFunction> array_function = InstallInternalArray( |
- builtin_exports, "InternalArray", FAST_HOLEY_ELEMENTS); |
+ Handle<JSFunction> array_function = |
+ InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS); |
native_context()->set_internal_array_function(*array_function); |
- InstallInternalArray(builtin_exports, "InternalPackedArray", FAST_ELEMENTS); |
+ } |
+ |
+ { |
+ InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS); |
} |
{ // -- S e t I t e r a t o r |
@@ -2204,15 +2181,13 @@ |
#undef INSTALL_PUBLIC_SYMBOL |
} |
- // Install natives. Everything exported to experimental natives is also |
- // shared to regular natives. |
- TransferNamedProperties(builtin_exports, shared); |
+ // Install natives. |
int i = Natives::GetDebuggerCount(); |
- if (!CompileBuiltin(isolate(), i, shared)) return false; |
+ if (!CompileBuiltin(isolate(), i)) return false; |
if (!InstallJSBuiltins(builtins)) return false; |
for (++i; i < Natives::GetBuiltinsCount(); ++i) { |
- if (!CompileBuiltin(isolate(), i, shared)) return false; |
+ if (!CompileBuiltin(isolate(), i)) return false; |
} |
InstallNativeFunctions(); |
@@ -2416,11 +2391,6 @@ |
} |
-void Genesis::RemoveExportObjects() { |
- native_context_->set_builtin_exports_object(Smi::FromInt(0)); |
-} |
- |
- |
static void InstallBuiltinFunctionId(Handle<JSObject> holder, |
const char* function_name, |
BuiltinFunctionId id) { |
@@ -2683,7 +2653,17 @@ |
} |
} |
// We do not expect this to throw an exception. Change this if it does. |
- bool result = CompileExtension(isolate, extension); |
+ Handle<String> source_code = |
+ isolate->factory() |
+ ->NewExternalStringFromOneByte(extension->source()) |
+ .ToHandleChecked(); |
+ bool result = CompileScriptCached(isolate, |
+ CStrVector(extension->name()), |
+ source_code, |
+ isolate->bootstrapper()->extensions_cache(), |
+ extension, |
+ Handle<Context>(isolate->context()), |
+ false); |
DCHECK(isolate->has_pending_exception() != result); |
if (!result) { |
// We print out the name of the extension that fail to install. |
@@ -2934,10 +2914,8 @@ |
// We can only de-serialize a context if the isolate was initialized from |
// a snapshot. Otherwise we have to build the context from scratch. |
- // Also create a context from scratch to expose natives, if required by flag. |
Handle<FixedArray> outdated_contexts; |
- if (FLAG_expose_natives_as != nullptr || |
- !isolate->initialized_from_snapshot() || |
+ if (!isolate->initialized_from_snapshot() || |
!Snapshot::NewContextFromSnapshot(isolate, global_proxy, |
&outdated_contexts) |
.ToHandle(&native_context_)) { |
@@ -2993,9 +2971,6 @@ |
InitializeExperimentalGlobal(); |
if (!InstallExperimentalNatives()) return; |
if (!InstallExtraNatives()) return; |
- |
- // Exports are no longer needed. |
- RemoveExportObjects(); |
} |
// The serializer cannot serialize typed arrays. Reset those typed arrays |