Revision: 3846
Author: [email protected]
Date: Fri Feb 12 06:05:46 2010
Log: * Use deserialized contexts when creating a new context through the API
where the API supplies a proxy global object. The proxy is connected
to the rest of the new context and the deserialized proxy from the
partial snapshot is discarded.
* Move the empty script from the context to the heap roots.
* Not quite done yet: Use the context deserializatin even when a
global template is provided by the API.
Since this is in an experimental branch I will TBR=ager it.
http://code.google.com/p/v8/source/detail?r=3846
Modified:
/branches/experimental/partial_snapshots/src/api.cc
/branches/experimental/partial_snapshots/src/bootstrapper.cc
/branches/experimental/partial_snapshots/src/contexts.h
/branches/experimental/partial_snapshots/src/debug.cc
/branches/experimental/partial_snapshots/src/heap.h
/branches/experimental/partial_snapshots/src/mksnapshot.cc
/branches/experimental/partial_snapshots/src/serialize.h
/branches/experimental/partial_snapshots/src/top.cc
=======================================
--- /branches/experimental/partial_snapshots/src/api.cc Fri Feb 5 01:40:21
2010
+++ /branches/experimental/partial_snapshots/src/api.cc Fri Feb 12 06:05:46
2010
@@ -2742,47 +2742,18 @@
LOG_API("Context::New");
ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
- // Handle the simple cases with partial snapshot deserialization.
- if (global_template.IsEmpty() && global_object.IsEmpty()) {
- // Enter V8 via an ENTER_V8 scope.
- Persistent<Context> result;
- {
- ENTER_V8;
- HandleScope scope;
#if defined(ANDROID)
- // On mobile device, full GC is expensive, leave it to the system to
- // decide when should make a full GC.
+ // On mobile device, full GC is expensive, leave it to the system to
+ // decide when should make a full GC.
#else
- // Give the heap a chance to cleanup if we've disposed contexts.
- i::Heap::CollectAllGarbageIfContextDisposed();
+ // Give the heap a chance to cleanup if we've disposed contexts.
+ i::Heap::CollectAllGarbageIfContextDisposed();
#endif
- i::Handle<i::Context> env = i::Snapshot::NewContextFromSnapshot();
- if (!env.is_null()) {
- if (i::Bootstrapper::InstallExtensions(env, extensions)) {
- i::Counters::contexts_created_by_snapshot.Increment();
- return Persistent<Context>::New(Utils::ToLocal(env));
- } else {
- return Persistent<Context>();
- }
- }
- // If there was no snapshot built into the VM then we fall through
to the
- // slow new context builder.
- }
- }
-
- i::Counters::contexts_created_from_scratch.Increment();
// Enter V8 via an ENTER_V8 scope.
i::Handle<i::Context> env;
{
ENTER_V8;
-#if defined(ANDROID)
- // On mobile device, full GC is expensive, leave it to the system to
- // decide when should make a full GC.
-#else
- // Give the heap a chance to cleanup if we've disposed contexts.
- i::Heap::CollectAllGarbageIfContextDisposed();
-#endif
v8::Handle<ObjectTemplate> proxy_template = global_template;
i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> global_constructor;
=======================================
--- /branches/experimental/partial_snapshots/src/bootstrapper.cc Fri Feb 5
01:40:21 2010
+++ /branches/experimental/partial_snapshots/src/bootstrapper.cc Fri Feb 12
06:05:46 2010
@@ -308,10 +308,34 @@
Handle<Context> global_context() { return global_context_; }
- void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
- Handle<Object> global_object);
+ // Creates some basic objects. Used for creating a context from scratch.
+ void CreateRoots();
+ // Creates the empty function. Used for creating a context from scratch.
+ Handle<JSFunction> CreateEmptyFunction();
+ // Creates the global objects using the global and the template passed in
+ // through the API. We call this regardless of whether we are building a
+ // context from scratch or using a deserialized one from the partial
snapshot
+ // but in the latter case we don't use the objects it produces directly,
as
+ // we have to used the deserialized ones that are linked together with
the
+ // rest of the context snapshot.
+ Handle<JSGlobalProxy> CreateNewGlobals(
+ v8::Handle<v8::ObjectTemplate> global_template,
+ Handle<Object> global_object,
+ Handle<GlobalObject>* global_proxy_out);
+ // Hooks the given global proxy into the context. If the context was
created
+ // by deserialization then this will unhook the global proxy that was
+ // deserialized, leaving the GC to pick it up.
+ void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
+ Handle<JSGlobalProxy> global_proxy);
+ // New context initialization. Used for creating a context from scratch.
+ void InitializeGlobal(Handle<GlobalObject> inner_global,
+ Handle<JSFunction> empty_function);
+ // Installs the contents of the native .js files on the global objects.
+ // Used for creating a context from scratch.
void InstallNativeFunctions();
bool InstallNatives();
+ // Used both for deserialized and from-scratch contexts to add the
extensions
+ // provided.
static bool InstallExtensions(Handle<Context> global_context,
v8::ExtensionConfiguration* extensions);
static bool InstallExtension(const char* name);
@@ -349,6 +373,7 @@
bool use_runtime_context);
Handle<Context> result_;
+ Handle<JSFunction> empty_function_;
BootstrapperActive active_;
friend class Bootstrapper;
};
@@ -374,13 +399,15 @@
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions) {
HandleScope scope;
+ Handle<Context> env;
Genesis genesis(global_object, global_template, extensions);
- if (!genesis.result().is_null()) {
- if (!InstallExtensions(genesis.result(), extensions)) {
- return Handle<Context>();
+ env = genesis.result();
+ if (!env.is_null()) {
+ if (InstallExtensions(env, extensions)) {
+ return env;
}
}
- return genesis.result();
+ return Handle<Context>();
}
@@ -481,22 +508,7 @@
}
-void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
- Handle<Object> global_object) {
- HandleScope scope;
- // Allocate the global context FixedArray first and then patch the
- // closure and extension object later (we need the empty function
- // and the global object, but in order to create those, we need the
- // global context).
- global_context_ =
- Handle<Context>::cast(
- GlobalHandles::Create(*Factory::NewGlobalContext()));
- Top::set_context(*global_context());
-
- // Allocate the message listeners object.
- v8::NeanderArray listeners;
- global_context()->set_message_listeners(*listeners.value());
-
+Handle<JSFunction> Genesis::CreateEmptyFunction() {
// Allocate the map for function instances.
Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
global_context()->set_function_instance_map(*fm);
@@ -540,137 +552,162 @@
Handle<JSFunction> empty_function =
Factory::NewFunction(symbol, Factory::null_value());
- { // --- E m p t y ---
- Handle<Code> code =
- Handle<Code>(Builtins::builtin(Builtins::EmptyFunction));
- empty_function->set_code(*code);
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("()
{}"));
- Handle<Script> script = Factory::NewScript(source);
- script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
- empty_function->shared()->set_script(*script);
- empty_function->shared()->set_start_position(0);
- empty_function->shared()->set_end_position(source->length());
- empty_function->shared()->DontAdaptArguments();
- global_context()->function_map()->set_prototype(*empty_function);
-
global_context()->function_instance_map()->set_prototype(*empty_function);
-
- // Allocate the function map first and then patch the prototype later
- Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm);
- empty_fm->set_instance_descriptors(*function_map_descriptors);
-
empty_fm->set_prototype(global_context()->object_function()->prototype());
- empty_function->set_map(*empty_fm);
- }
-
- { // --- G l o b a l ---
- // Step 1: create a fresh inner JSGlobalObject
- Handle<GlobalObject> object;
- {
- Handle<JSFunction> js_global_function;
- Handle<ObjectTemplateInfo> js_global_template;
- if (!global_template.IsEmpty()) {
- // Get prototype template of the global_template
- Handle<ObjectTemplateInfo> data =
- v8::Utils::OpenHandle(*global_template);
- Handle<FunctionTemplateInfo> global_constructor =
- Handle<FunctionTemplateInfo>(
- FunctionTemplateInfo::cast(data->constructor()));
- Handle<Object>
proto_template(global_constructor->prototype_template());
- if (!proto_template->IsUndefined()) {
- js_global_template =
- Handle<ObjectTemplateInfo>::cast(proto_template);
- }
- }
-
- if (js_global_template.is_null()) {
- Handle<String> name = Handle<String>(Heap::empty_symbol());
- Handle<Code> code =
Handle<Code>(Builtins::builtin(Builtins::Illegal));
- js_global_function =
- Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
- JSGlobalObject::kSize, code, true);
- // Change the constructor property of the prototype of the
- // hidden global function to refer to the Object function.
- Handle<JSObject> prototype =
- Handle<JSObject>(
- JSObject::cast(js_global_function->instance_prototype()));
- SetProperty(prototype, Factory::constructor_symbol(),
- Top::object_function(), NONE);
- } else {
- Handle<FunctionTemplateInfo> js_global_constructor(
- FunctionTemplateInfo::cast(js_global_template->constructor()));
- js_global_function =
- Factory::CreateApiFunction(js_global_constructor,
- Factory::InnerGlobalObject);
- }
-
- js_global_function->initial_map()->set_is_hidden_prototype();
- object = Factory::NewGlobalObject(js_global_function);
- }
-
- // Set the global context for the global object.
- object->set_global_context(*global_context());
-
- // Step 2: create or re-initialize the global proxy object.
- Handle<JSGlobalProxy> global_proxy;
- {
- Handle<JSFunction> global_proxy_function;
- if (global_template.IsEmpty()) {
- Handle<String> name = Handle<String>(Heap::empty_symbol());
- Handle<Code> code =
Handle<Code>(Builtins::builtin(Builtins::Illegal));
- global_proxy_function =
- Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE,
- JSGlobalProxy::kSize, code, true);
- } else {
- Handle<ObjectTemplateInfo> data =
- v8::Utils::OpenHandle(*global_template);
- Handle<FunctionTemplateInfo> global_constructor(
- FunctionTemplateInfo::cast(data->constructor()));
- global_proxy_function =
- Factory::CreateApiFunction(global_constructor,
- Factory::OuterGlobalObject);
- }
-
- Handle<String> global_name = Factory::LookupAsciiSymbol("global");
-
global_proxy_function->shared()->set_instance_class_name(*global_name);
-
global_proxy_function->initial_map()->set_is_access_check_needed(true);
-
- // Set global_proxy.__proto__ to js_global after
ConfigureGlobalObjects
-
- if (global_object.location() != NULL) {
- ASSERT(global_object->IsJSGlobalProxy());
- global_proxy =
- ReinitializeJSGlobalProxy(
- global_proxy_function,
- Handle<JSGlobalProxy>::cast(global_object));
- } else {
- global_proxy = Handle<JSGlobalProxy>::cast(
- Factory::NewJSObject(global_proxy_function, TENURED));
- }
-
- // Security setup: Set the security token of the global object to
- // its the inner global. This makes the security check between two
- // different contexts fail by default even in case of global
- // object reinitialization.
- object->set_global_receiver(*global_proxy);
- global_proxy->set_context(*global_context());
- }
-
- { // --- G l o b a l C o n t e x t ---
- // use the empty function as closure (no scope info)
- global_context()->set_closure(*empty_function);
- global_context()->set_fcontext(*global_context());
- global_context()->set_previous(NULL);
-
- // set extension and global object
- global_context()->set_extension(*object);
- global_context()->set_global(*object);
- global_context()->set_global_proxy(*global_proxy);
- // use inner global object as security token by default
- global_context()->set_security_token(*object);
- }
-
- Handle<JSObject> global = Handle<JSObject>(global_context()->global());
- SetProperty(global, object_name, Top::object_function(), DONT_ENUM);
- }
+ // --- E m p t y ---
+ Handle<Code> code =
+ Handle<Code>(Builtins::builtin(Builtins::EmptyFunction));
+ empty_function->set_code(*code);
+ Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}"));
+ Handle<Script> script = Factory::NewScript(source);
+ script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
+ empty_function->shared()->set_script(*script);
+ empty_function->shared()->set_start_position(0);
+ empty_function->shared()->set_end_position(source->length());
+ empty_function->shared()->DontAdaptArguments();
+ global_context()->function_map()->set_prototype(*empty_function);
+
global_context()->function_instance_map()->set_prototype(*empty_function);
+
+ // Allocate the function map first and then patch the prototype later
+ Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm);
+ empty_fm->set_instance_descriptors(*function_map_descriptors);
+
empty_fm->set_prototype(global_context()->object_function()->prototype());
+ empty_function->set_map(*empty_fm);
+ return empty_function;
+}
+
+
+void Genesis::CreateRoots() {
+ // Allocate the global context FixedArray first and then patch the
+ // closure and extension object later (we need the empty function
+ // and the global object, but in order to create those, we need the
+ // global context).
+ global_context_ =
+ Handle<Context>::cast(
+ GlobalHandles::Create(*Factory::NewGlobalContext()));
+ Top::set_context(*global_context());
+
+ // Allocate the message listeners object.
+ {
+ v8::NeanderArray listeners;
+ global_context()->set_message_listeners(*listeners.value());
+ }
+}
+
+
+Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
+ v8::Handle<v8::ObjectTemplate> global_template,
+ Handle<Object> global_object,
+ Handle<GlobalObject>* inner_global_out) {
+ // --- G l o b a l ---
+ // Step 1: Create a fresh inner JSGlobalObject.
+ Handle<JSFunction> js_global_function;
+ Handle<ObjectTemplateInfo> js_global_template;
+ if (!global_template.IsEmpty()) {
+ // Get prototype template of the global_template.
+ Handle<ObjectTemplateInfo> data =
+ v8::Utils::OpenHandle(*global_template);
+ Handle<FunctionTemplateInfo> global_constructor =
+ Handle<FunctionTemplateInfo>(
+ FunctionTemplateInfo::cast(data->constructor()));
+ Handle<Object>
proto_template(global_constructor->prototype_template());
+ if (!proto_template->IsUndefined()) {
+ js_global_template =
+ Handle<ObjectTemplateInfo>::cast(proto_template);
+ }
+ }
+
+ if (js_global_template.is_null()) {
+ Handle<String> name = Handle<String>(Heap::empty_symbol());
+ Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ js_global_function =
+ Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
+ JSGlobalObject::kSize, code, true);
+ // Change the constructor property of the prototype of the
+ // hidden global function to refer to the Object function.
+ Handle<JSObject> prototype =
+ Handle<JSObject>(
+ JSObject::cast(js_global_function->instance_prototype()));
+ SetProperty(prototype, Factory::constructor_symbol(),
+ Top::object_function(), NONE);
+ } else {
+ Handle<FunctionTemplateInfo> js_global_constructor(
+ FunctionTemplateInfo::cast(js_global_template->constructor()));
+ js_global_function =
+ Factory::CreateApiFunction(js_global_constructor,
+ Factory::InnerGlobalObject);
+ }
+
+ js_global_function->initial_map()->set_is_hidden_prototype();
+ Handle<GlobalObject> inner_global =
+ Factory::NewGlobalObject(js_global_function);
+ if (inner_global_out != NULL) {
+ *inner_global_out = inner_global;
+ }
+
+ // Step 2: create or re-initialize the global proxy object.
+ Handle<JSFunction> global_proxy_function;
+ if (global_template.IsEmpty()) {
+ Handle<String> name = Handle<String>(Heap::empty_symbol());
+ Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ global_proxy_function =
+ Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE,
+ JSGlobalProxy::kSize, code, true);
+ } else {
+ Handle<ObjectTemplateInfo> data =
+ v8::Utils::OpenHandle(*global_template);
+ Handle<FunctionTemplateInfo> global_constructor(
+ FunctionTemplateInfo::cast(data->constructor()));
+ global_proxy_function =
+ Factory::CreateApiFunction(global_constructor,
+ Factory::OuterGlobalObject);
+ }
+
+ Handle<String> global_name = Factory::LookupAsciiSymbol("global");
+ global_proxy_function->shared()->set_instance_class_name(*global_name);
+ global_proxy_function->initial_map()->set_is_access_check_needed(true);
+
+ // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
+ // Return the global proxy.
+
+ if (global_object.location() != NULL) {
+ ASSERT(global_object->IsJSGlobalProxy());
+ return ReinitializeJSGlobalProxy(
+ global_proxy_function,
+ Handle<JSGlobalProxy>::cast(global_object));
+ } else {
+ return Handle<JSGlobalProxy>::cast(
+ Factory::NewJSObject(global_proxy_function, TENURED));
+ }
+}
+
+
+void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
+ Handle<JSGlobalProxy> global_proxy) {
+ // Set the global context for the global object.
+ inner_global->set_global_context(*global_context());
+ inner_global->set_global_receiver(*global_proxy);
+ global_proxy->set_context(*global_context());
+ global_context()->set_global_proxy(*global_proxy);
+}
+
+
+void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
+ Handle<JSFunction> empty_function) {
+ // --- G l o b a l C o n t e x t ---
+ // Use the empty function as closure (no scope info).
+ global_context()->set_closure(*empty_function);
+ global_context()->set_fcontext(*global_context());
+ global_context()->set_previous(NULL);
+ // Set extension and global object.
+ global_context()->set_extension(*inner_global);
+ global_context()->set_global(*inner_global);
+ // Security setup: Set the security token of the global object to
+ // its the inner global. This makes the security check between two
+ // different contexts fail by default even in case of global
+ // object reinitialization.
+ global_context()->set_security_token(*inner_global);
+
+ Handle<String> object_name = Handle<String>(Heap::Object_symbol());
+ SetProperty(inner_global, object_name, Top::object_function(),
DONT_ENUM);
Handle<JSObject> global = Handle<JSObject>(global_context()->global());
@@ -1151,7 +1188,7 @@
// Allocate the empty script.
Handle<Script> script = Factory::NewScript(Factory::empty_string());
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
- global_context()->set_empty_script(*script);
+ Heap::public_set_empty_script(*script);
}
// Install natives.
@@ -1567,7 +1604,6 @@
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions) {
result_ = Handle<Context>::null();
-
// If V8 isn't running and cannot be initialized, just return.
if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
@@ -1576,14 +1612,46 @@
HandleScope scope;
SaveContext saved_context;
- CreateRoots(global_template, global_object);
-
- if (!InstallNatives()) return;
-
- MakeFunctionInstancePrototypeWritable();
- BuildSpecialFunctionTable();
-
- if (!ConfigureGlobalObjects(global_template)) return;
+ if (global_template.IsEmpty()) {
+ Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
+ if (!new_context.is_null()) {
+ global_context_ =
+ Handle<Context>::cast(GlobalHandles::Create(*new_context));
+ Top::set_context(*global_context_);
+ i::Counters::contexts_created_by_snapshot.Increment();
+ result_ = global_context_;
+ JSFunction* empty_function =
+ JSFunction::cast(result_->function_map()->prototype());
+ empty_function_ = Handle<JSFunction>(empty_function);
+ Handle<JSGlobalProxy> global_proxy =
+ CreateNewGlobals(global_template, global_object, NULL);
+ // CreateNewGlobals can return an inner global that it just made, but
+ // we will ignore that because we want to hook up the global proxy to
+ // the one from the snapshot.
+ Handle<GlobalObject> inner_global(
+ GlobalObject::cast(global_context_->extension()));
+ HookUpGlobalProxy(inner_global, global_proxy);
+ if (!ConfigureGlobalObjects(global_template)) return;
+ }
+ }
+ if (global_context_.is_null()) {
+ // We get here if there either was no context snapshot or we couldn't
use
+ // the context snapshot because we were supplied with a global
template.
+ CreateRoots();
+ Handle<JSFunction> empty_function = CreateEmptyFunction();
+ Handle<GlobalObject> inner_global;
+ Handle<JSGlobalProxy> global_proxy =
+ CreateNewGlobals(global_template, global_object, &inner_global);
+ HookUpGlobalProxy(inner_global, global_proxy);
+ InitializeGlobal(inner_global, empty_function);
+ if (!InstallNatives()) return;
+
+ MakeFunctionInstancePrototypeWritable();
+ BuildSpecialFunctionTable();
+
+ if (!ConfigureGlobalObjects(global_template)) return;
+ i::Counters::contexts_created_from_scratch.Increment();
+ }
result_ = global_context_;
}
=======================================
--- /branches/experimental/partial_snapshots/src/contexts.h Tue Jan 5
01:38:02 2010
+++ /branches/experimental/partial_snapshots/src/contexts.h Fri Feb 12
06:05:46 2010
@@ -94,7 +94,6 @@
V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction,
call_as_function_delegate) \
V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
call_as_constructor_delegate) \
- V(EMPTY_SCRIPT_INDEX, Script, empty_script) \
V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction,
context_extension_function) \
V(OUT_OF_MEMORY_INDEX, Object, out_of_memory) \
@@ -215,7 +214,6 @@
RUNTIME_CONTEXT_INDEX,
CALL_AS_FUNCTION_DELEGATE_INDEX,
CALL_AS_CONSTRUCTOR_DELEGATE_INDEX,
- EMPTY_SCRIPT_INDEX,
SCRIPT_FUNCTION_INDEX,
CONTEXT_EXTENSION_FUNCTION_INDEX,
OUT_OF_MEMORY_INDEX,
=======================================
--- /branches/experimental/partial_snapshots/src/debug.cc Wed Feb 3
02:52:22 2010
+++ /branches/experimental/partial_snapshots/src/debug.cc Fri Feb 12
06:05:46 2010
@@ -1679,7 +1679,7 @@
// Perform two GCs to get rid of all unreferenced scripts. The first GC
gets
// rid of all the cached script wrappers and the second gets rid of the
- // scripts which is no longer referenced.
+ // scripts which are no longer referenced.
Heap::CollectAllGarbage(false);
Heap::CollectAllGarbage(false);
=======================================
--- /branches/experimental/partial_snapshots/src/heap.h Thu Feb 4 00:02:41
2010
+++ /branches/experimental/partial_snapshots/src/heap.h Fri Feb 12 06:05:46
2010
@@ -106,6 +106,7 @@
V(FixedArray, single_character_string_cache,
SingleCharacterStringCache) \
V(FixedArray, natives_source_cache,
NativesSourceCache) \
V(Object, last_script_id,
LastScriptId) \
+ V(Script, empty_script,
EmptyScript) \
V(Smi, real_stack_limit,
RealStackLimit) \
#if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP
@@ -733,6 +734,10 @@
static void public_set_non_monomorphic_cache(NumberDictionary* value) {
roots_[kNonMonomorphicCacheRootIndex] = value;
}
+
+ static void public_set_empty_script(Script* script) {
+ roots_[kEmptyScriptRootIndex] = script;
+ }
// Update the next script id.
static inline void SetLastScriptId(Object* last_script_id);
=======================================
--- /branches/experimental/partial_snapshots/src/mksnapshot.cc Thu Feb 4
00:02:41 2010
+++ /branches/experimental/partial_snapshots/src/mksnapshot.cc Fri Feb 12
06:05:46 2010
@@ -229,7 +229,6 @@
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of the context.
i::Heap::CollectAllGarbage(true);
- i::AssertNoAllocation we_have_raw_pointers_here;
i::Object* raw_context = *(v8::Utils::OpenHandle(*context));
context.Dispose();
CppByteSink sink(argv[1]);
=======================================
--- /branches/experimental/partial_snapshots/src/serialize.h Thu Feb 4
00:02:41 2010
+++ /branches/experimental/partial_snapshots/src/serialize.h Fri Feb 12
06:05:46 2010
@@ -497,6 +497,11 @@
virtual int RootIndex(HeapObject* o);
virtual int PartialSnapshotCacheIndex(HeapObject* o);
virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) {
+ // Scripts should be referred only through shared function infos. We
can't
+ // allow them to be part of the partial snapshot because they contain a
+ // unique ID, and deserializing several partial snapshots containing
script
+ // would cause dupes.
+ ASSERT(!o->IsScript());
return o->IsString() || o->IsSharedFunctionInfo() || o->IsHeapNumber();
}
=======================================
--- /branches/experimental/partial_snapshots/src/top.cc Mon Nov 16 08:58:09
2009
+++ /branches/experimental/partial_snapshots/src/top.cc Fri Feb 12 06:05:46
2010
@@ -668,7 +668,7 @@
void Top::ComputeLocation(MessageLocation* target) {
- *target = MessageLocation(empty_script(), -1, -1);
+ *target = MessageLocation(Handle<Script>(Heap::empty_script()), -1, -1);
StackTraceFrameIterator it;
if (!it.done()) {
JavaScriptFrame* frame = it.frame();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev