Serializer: use opcode to signal new chunk.
authoryangguo <yangguo@chromium.org>
Fri, 28 Nov 2014 12:07:40 +0000 (04:07 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 28 Nov 2014 12:07:49 +0000 (12:07 +0000)
R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/757813003

Cr-Commit-Position: refs/heads/master@{#25566}

src/serialize.cc
src/serialize.h

index db90792..fab9775 100644 (file)
@@ -860,8 +860,8 @@ void Deserializer::ReadObject(int space_number, Object** write_back) {
 // to do is to bump up the pointer for each space in the reserved
 // space. This is also used for fixing back references.
 // We may have to split up the pre-allocation into several chunks
-// because it would not fit onto a single page, we have to keep track
-// of when to move to the next chunk.
+// because it would not fit onto a single page. We do not have to keep
+// track of when to move to the next chunk. An opcode will signal this.
 // Since multiple large objects cannot be folded into one large object
 // space allocation, we have to do an actual allocation when deserializing
 // each large object. Instead of tracking offset for back references, we
@@ -879,20 +879,13 @@ Address Deserializer::Allocate(int space_index, int size) {
     DCHECK(space_index < kNumberOfPreallocatedSpaces);
     Address address = high_water_[space_index];
     DCHECK_NE(NULL, address);
+    high_water_[space_index] += size;
+#ifdef DEBUG
+    // Assert that the current reserved chunk is still big enough.
     const Heap::Reservation& reservation = reservations_[space_index];
     int chunk_index = current_chunk_[space_index];
-    if (address + size > reservation[chunk_index].end) {
-      // The last chunk size matches exactly the already deserialized data.
-      DCHECK_EQ(address, reservation[chunk_index].end);
-      // Move to next reserved chunk.
-      chunk_index = ++current_chunk_[space_index];
-      DCHECK_LT(chunk_index, reservation.length());
-      // Prepare for next allocation in the next chunk.
-      address = reservation[chunk_index].start;
-    } else {
-      high_water_[space_index] = address + size;
-    }
-    high_water_[space_index] = address + size;
+    CHECK_LE(high_water_[space_index], reservation[chunk_index].end);
+#endif
     return address;
   }
 }
@@ -1254,6 +1247,20 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
         break;
       }
 
+      case kNextChunk: {
+        int space = source_->Get();
+        DCHECK(space < kNumberOfPreallocatedSpaces);
+        int chunk_index = current_chunk_[space];
+        const Heap::Reservation& reservation = reservations_[space];
+        // Make sure the current chunk is indeed exhausted.
+        CHECK_EQ(reservation[chunk_index].end, high_water_[space]);
+        // Move to next reserved chunk.
+        chunk_index = ++current_chunk_[space];
+        DCHECK_LT(chunk_index, reservation.length());
+        high_water_[space] = reservation[chunk_index].start;
+        break;
+      }
+
       case kSynchronize: {
         // If we get here then that indicates that you have a mismatch between
         // the number of GC roots when serializing and deserializing.
@@ -1565,20 +1572,6 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
 
 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
                                                      int size, Map* map) {
-  int reserved_size = size;
-
-  sink_->Put(kNewObject + reference_representation_ + space,
-             "ObjectSerialization");
-  // Objects on the large object space are always double-aligned.
-  if (space != LO_SPACE && object_->NeedsToEnsureDoubleAlignment()) {
-    sink_->PutInt(kDoubleAlignmentSentinel, "double align next object");
-    // Add wriggle room for double alignment padding.
-    reserved_size += kPointerSize;
-  }
-  int encoded_size = size >> kObjectAlignmentBits;
-  DCHECK_NE(kDoubleAlignmentSentinel, encoded_size);
-  sink_->PutInt(encoded_size, "Size in words");
-
   if (serializer_->code_address_map_) {
     const char* code_name =
         serializer_->code_address_map_->Lookup(object_->address());
@@ -1588,9 +1581,11 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
         SnapshotPositionEvent(object_->address(), sink_->Position()));
   }
 
-  // Mark this object as already serialized.
   BackReference back_reference;
   if (space == LO_SPACE) {
+    sink_->Put(kNewObject + reference_representation_ + space,
+               "new large object");
+    sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
     if (object_->IsCode()) {
       sink_->Put(EXECUTABLE, "executable large object");
     } else {
@@ -1598,8 +1593,20 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
     }
     back_reference = serializer_->AllocateLargeObject(size);
   } else {
-    back_reference = serializer_->Allocate(space, reserved_size);
+    if (object_->NeedsToEnsureDoubleAlignment()) {
+      // Add wriggle room for double alignment padding.
+      back_reference = serializer_->Allocate(space, size + kPointerSize);
+      sink_->PutInt(kDoubleAlignmentSentinel, "double align");
+    } else {
+      back_reference = serializer_->Allocate(space, size);
+    }
+    sink_->Put(kNewObject + reference_representation_ + space, "new object");
+    int encoded_size = size >> kObjectAlignmentBits;
+    DCHECK_NE(kDoubleAlignmentSentinel, encoded_size);
+    sink_->PutInt(encoded_size, "Size in words");
   }
+
+  // Mark this object as already serialized.
   serializer_->back_reference_map()->Add(object_, back_reference);
 
   // Serialize the map (first word of the object).
@@ -1950,6 +1957,8 @@ BackReference Serializer::Allocate(AllocationSpace space, int size) {
   if (new_chunk_size > max_chunk_size(space)) {
     // The new chunk size would not fit onto a single page. Complete the
     // current chunk and start a new one.
+    sink_->Put(kNextChunk, "move to next chunk");
+    sink_->Put(space, "space of next chunk");
     completed_chunks_[space].Add(pending_chunk_[space]);
     pending_chunk_[space] = 0;
     new_chunk_size = size;
index 36854b1..3bb0e1a 100644 (file)
@@ -377,6 +377,8 @@ class SerializerDeserializer: public ObjectVisitor {
 
   static const int kNop = 0xf;  // Do nothing, used for padding.
 
+  static const int kNextChunk = 0x4f;  // Move to next reserved chunk.
+
   static const int kAnyOldSpace = -1;
 
   // A bitmask for getting the space out of an instruction.