Index: src/serialize.cc |
=================================================================== |
--- src/serialize.cc (revision 11803) |
+++ src/serialize.cc (working copy) |
@@ -37,6 +37,7 @@ |
#include "platform.h" |
#include "runtime.h" |
#include "serialize.h" |
+#include "snapshot.h" |
#include "stub-cache.h" |
#include "v8threads.h" |
@@ -674,10 +675,6 @@ |
ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); |
// No active handles. |
ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty()); |
- // Make sure the entire partial snapshot cache is traversed, filling it with |
- // valid object pointers. |
- isolate_->set_serialize_partial_snapshot_cache_length( |
- Isolate::kPartialSnapshotCacheCapacity); |
ASSERT_EQ(NULL, external_reference_decoder_); |
external_reference_decoder_ = new ExternalReferenceDecoder(); |
isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
@@ -1149,22 +1146,6 @@ |
void PartialSerializer::Serialize(Object** object) { |
this->VisitPointer(object); |
- Isolate* isolate = Isolate::Current(); |
- |
- // After we have done the partial serialization the partial snapshot cache |
- // will contain some references needed to decode the partial snapshot. We |
- // fill it up with undefineds so it has a predictable length so the |
- // deserialization code doesn't need to know the length. |
- for (int index = isolate->serialize_partial_snapshot_cache_length(); |
- index < Isolate::kPartialSnapshotCacheCapacity; |
- index++) { |
- isolate->serialize_partial_snapshot_cache()[index] = |
- isolate->heap()->undefined_value(); |
- startup_serializer_->VisitPointer( |
- &isolate->serialize_partial_snapshot_cache()[index]); |
- } |
- isolate->set_serialize_partial_snapshot_cache_length( |
- Isolate::kPartialSnapshotCacheCapacity); |
} |
@@ -1194,29 +1175,32 @@ |
// This ensures that the partial snapshot cache keeps things alive during GC and |
// tracks their movement. When it is called during serialization of the startup |
-// snapshot the partial snapshot is empty, so nothing happens. When the partial |
-// (context) snapshot is created, this array is populated with the pointers that |
-// the partial snapshot will need. As that happens we emit serialized objects to |
-// the startup snapshot that correspond to the elements of this cache array. On |
-// deserialization we therefore need to visit the cache array. This fills it up |
-// with pointers to deserialized objects. |
+// snapshot nothing happens. When the partial (context) snapshot is created, |
+// this array is populated with the pointers that the partial snapshot will |
+// need. As that happens we emit serialized objects to the startup snapshot |
+// that correspond to the elements of this cache array. On deserialization we |
+// therefore need to visit the cache array. This fills it up with pointers to |
+// deserialized objects. |
void SerializerDeserializer::Iterate(ObjectVisitor* visitor) { |
+ if (Serializer::enabled()) return; |
Isolate* isolate = Isolate::Current(); |
- visitor->VisitPointers( |
- isolate->serialize_partial_snapshot_cache(), |
- &isolate->serialize_partial_snapshot_cache()[ |
- isolate->serialize_partial_snapshot_cache_length()]); |
+ for (int i = 0; ; i++) { |
+ if (isolate->serialize_partial_snapshot_cache_length() <= i) { |
+ // Extend the array ready to get a value from the visitor when |
+ // deserializing. |
+ isolate->PushToPartialSnapshotCache(Smi::FromInt(0)); |
+ } |
+ Object** cache = isolate->serialize_partial_snapshot_cache(); |
+ visitor->VisitPointers(&cache[i], &cache[i + 1]); |
+ // Sentinel is the undefined object, which is a root so it will not normally |
+ // be found in the cache. |
+ if (cache[i] == isolate->heap()->undefined_value()) { |
+ break; |
+ } |
+ } |
} |
-// When deserializing we need to set the size of the snapshot cache. This means |
-// the root iteration code (above) will iterate over array elements, writing the |
-// references to deserialized objects in them. |
-void SerializerDeserializer::SetSnapshotCacheSize(int size) { |
- Isolate::Current()->set_serialize_partial_snapshot_cache_length(size); |
-} |
- |
- |
int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) { |
Isolate* isolate = Isolate::Current(); |
@@ -1231,14 +1215,11 @@ |
// then visit the pointer so that it becomes part of the startup snapshot |
// and we can refer to it from the partial snapshot. |
int length = isolate->serialize_partial_snapshot_cache_length(); |
- CHECK(length < Isolate::kPartialSnapshotCacheCapacity); |
- isolate->serialize_partial_snapshot_cache()[length] = heap_object; |
- startup_serializer_->VisitPointer( |
- &isolate->serialize_partial_snapshot_cache()[length]); |
+ isolate->PushToPartialSnapshotCache(heap_object); |
+ startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); |
// We don't recurse from the startup snapshot generator into the partial |
// snapshot generator. |
- ASSERT(length == isolate->serialize_partial_snapshot_cache_length()); |
- isolate->set_serialize_partial_snapshot_cache_length(length + 1); |
+ ASSERT(length == isolate->serialize_partial_snapshot_cache_length() - 1); |
return length; |
} |
@@ -1337,12 +1318,14 @@ |
void StartupSerializer::SerializeWeakReferences() { |
- for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length(); |
- i < Isolate::kPartialSnapshotCacheCapacity; |
- i++) { |
- sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization"); |
- sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index"); |
- } |
+ // This phase comes right after the partial serialization (of the snapshot). |
+ // After we have done the partial serialization the partial snapshot cache |
+ // will contain some references needed to decode the partial snapshot. We |
+ // add one entry with 'undefined' which is the sentinel that the deserializer |
+ // uses to know it is done deserializing the array. |
+ Isolate* isolate = Isolate::Current(); |
+ Object* undefined = isolate->heap()->undefined_value(); |
+ VisitPointer(&undefined); |
HEAP->IterateWeakRoots(this, VISIT_ALL); |
} |