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

Reply via email to