Update V8 to r4730 as required by WebKit r60469
diff --git a/src/serialize.cc b/src/serialize.cc
index dcaa101..06c6df7 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -660,27 +660,164 @@
 }
 
 
-#define ONE_CASE_PER_SPACE(base_tag)   \
-  case (base_tag) + NEW_SPACE:         /* NOLINT */ \
-  case (base_tag) + OLD_POINTER_SPACE: /* NOLINT */ \
-  case (base_tag) + OLD_DATA_SPACE:    /* NOLINT */ \
-  case (base_tag) + CODE_SPACE:        /* NOLINT */ \
-  case (base_tag) + MAP_SPACE:         /* NOLINT */ \
-  case (base_tag) + CELL_SPACE:        /* NOLINT */ \
-  case (base_tag) + kLargeData:        /* NOLINT */ \
-  case (base_tag) + kLargeCode:        /* NOLINT */ \
-  case (base_tag) + kLargeFixedArray:  /* NOLINT */
+// This macro is always used with a constant argument so it should all fold
+// away to almost nothing in the generated code.  It might be nicer to do this
+// with the ternary operator but there are type issues with that.
+#define ASSIGN_DEST_SPACE(space_number)                                        \
+  Space* dest_space;                                                           \
+  if (space_number == NEW_SPACE) {                                             \
+    dest_space = Heap::new_space();                                            \
+  } else if (space_number == OLD_POINTER_SPACE) {                              \
+    dest_space = Heap::old_pointer_space();                                    \
+  } else if (space_number == OLD_DATA_SPACE) {                                 \
+    dest_space = Heap::old_data_space();                                       \
+  } else if (space_number == CODE_SPACE) {                                     \
+    dest_space = Heap::code_space();                                           \
+  } else if (space_number == MAP_SPACE) {                                      \
+    dest_space = Heap::map_space();                                            \
+  } else if (space_number == CELL_SPACE) {                                     \
+    dest_space = Heap::cell_space();                                           \
+  } else {                                                                     \
+    ASSERT(space_number >= LO_SPACE);                                          \
+    dest_space = Heap::lo_space();                                             \
+  }
+
+
+static const int kUnknownOffsetFromStart = -1;
 
 
 void Deserializer::ReadChunk(Object** current,
                              Object** limit,
-                             int space,
+                             int source_space,
                              Address address) {
   while (current < limit) {
     int data = source_->Get();
     switch (data) {
+#define CASE_STATEMENT(where, how, within, space_number)                       \
+      case where + how + within + space_number:                                \
+      ASSERT((where & ~kPointedToMask) == 0);                                  \
+      ASSERT((how & ~kHowToCodeMask) == 0);                                    \
+      ASSERT((within & ~kWhereToPointMask) == 0);                              \
+      ASSERT((space_number & ~kSpaceMask) == 0);
+
+#define CASE_BODY(where, how, within, space_number_if_any, offset_from_start)  \
+      {                                                                        \
+        bool emit_write_barrier = false;                                       \
+        bool current_was_incremented = false;                                  \
+        int space_number =  space_number_if_any == kAnyOldSpace ?              \
+                            (data & kSpaceMask) : space_number_if_any;         \
+        if (where == kNewObject && how == kPlain && within == kStartOfObject) {\
+          ASSIGN_DEST_SPACE(space_number)                                      \
+          ReadObject(space_number, dest_space, current);                       \
+          emit_write_barrier =                                                 \
+            (space_number == NEW_SPACE && source_space != NEW_SPACE);          \
+        } else {                                                               \
+          Object* new_object = NULL;  /* May not be a real Object pointer. */  \
+          if (where == kNewObject) {                                           \
+            ASSIGN_DEST_SPACE(space_number)                                    \
+            ReadObject(space_number, dest_space, &new_object);                 \
+          } else if (where == kRootArray) {                                    \
+            int root_id = source_->GetInt();                                   \
+            new_object = Heap::roots_address()[root_id];                       \
+          } else if (where == kPartialSnapshotCache) {                         \
+            int cache_index = source_->GetInt();                               \
+            new_object = partial_snapshot_cache_[cache_index];                 \
+          } else if (where == kExternalReference) {                            \
+            int reference_id = source_->GetInt();                              \
+            Address address =                                                  \
+                external_reference_decoder_->Decode(reference_id);             \
+            new_object = reinterpret_cast<Object*>(address);                   \
+          } else if (where == kBackref) {                                      \
+            emit_write_barrier =                                               \
+              (space_number == NEW_SPACE && source_space != NEW_SPACE);        \
+            new_object = GetAddressFromEnd(data & kSpaceMask);                 \
+          } else {                                                             \
+            ASSERT(where == kFromStart);                                       \
+            if (offset_from_start == kUnknownOffsetFromStart) {                \
+              emit_write_barrier =                                             \
+                (space_number == NEW_SPACE && source_space != NEW_SPACE);      \
+              new_object = GetAddressFromStart(data & kSpaceMask);             \
+            } else {                                                           \
+              Address object_address = pages_[space_number][0] +               \
+                  (offset_from_start << kObjectAlignmentBits);                 \
+              new_object = HeapObject::FromAddress(object_address);            \
+            }                                                                  \
+          }                                                                    \
+          if (within == kFirstInstruction) {                                   \
+            Code* new_code_object = reinterpret_cast<Code*>(new_object);       \
+            new_object = reinterpret_cast<Object*>(                            \
+                new_code_object->instruction_start());                         \
+          }                                                                    \
+          if (how == kFromCode) {                                              \
+            Address location_of_branch_data =                                  \
+                reinterpret_cast<Address>(current);                            \
+            Assembler::set_target_at(location_of_branch_data,                  \
+                                     reinterpret_cast<Address>(new_object));   \
+            if (within == kFirstInstruction) {                                 \
+              location_of_branch_data += Assembler::kCallTargetSize;           \
+              current = reinterpret_cast<Object**>(location_of_branch_data);   \
+              current_was_incremented = true;                                  \
+            }                                                                  \
+          } else {                                                             \
+            *current = new_object;                                             \
+          }                                                                    \
+        }                                                                      \
+        if (emit_write_barrier) {                                              \
+          Heap::RecordWrite(address, static_cast<int>(                         \
+              reinterpret_cast<Address>(current) - address));                  \
+        }                                                                      \
+        if (!current_was_incremented) {                                        \
+          current++;   /* Increment current if it wasn't done above. */        \
+        }                                                                      \
+        break;                                                                 \
+      }                                                                        \
+
+// This generates a case and a body for each space.  The large object spaces are
+// very rare in snapshots so they are grouped in one body.
+#define ONE_PER_SPACE(where, how, within)                                      \
+  CASE_STATEMENT(where, how, within, NEW_SPACE)                                \
+  CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart)            \
+  CASE_STATEMENT(where, how, within, OLD_DATA_SPACE)                           \
+  CASE_BODY(where, how, within, OLD_DATA_SPACE, kUnknownOffsetFromStart)       \
+  CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE)                        \
+  CASE_BODY(where, how, within, OLD_POINTER_SPACE, kUnknownOffsetFromStart)    \
+  CASE_STATEMENT(where, how, within, CODE_SPACE)                               \
+  CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart)           \
+  CASE_STATEMENT(where, how, within, CELL_SPACE)                               \
+  CASE_BODY(where, how, within, CELL_SPACE, kUnknownOffsetFromStart)           \
+  CASE_STATEMENT(where, how, within, MAP_SPACE)                                \
+  CASE_BODY(where, how, within, MAP_SPACE, kUnknownOffsetFromStart)            \
+  CASE_STATEMENT(where, how, within, kLargeData)                               \
+  CASE_STATEMENT(where, how, within, kLargeCode)                               \
+  CASE_STATEMENT(where, how, within, kLargeFixedArray)                         \
+  CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
+
+// This generates a case and a body for the new space (which has to do extra
+// write barrier handling) and handles the other spaces with 8 fall-through
+// cases and one body.
+#define ALL_SPACES(where, how, within)                                         \
+  CASE_STATEMENT(where, how, within, NEW_SPACE)                                \
+  CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart)            \
+  CASE_STATEMENT(where, how, within, OLD_DATA_SPACE)                           \
+  CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE)                        \
+  CASE_STATEMENT(where, how, within, CODE_SPACE)                               \
+  CASE_STATEMENT(where, how, within, CELL_SPACE)                               \
+  CASE_STATEMENT(where, how, within, MAP_SPACE)                                \
+  CASE_STATEMENT(where, how, within, kLargeData)                               \
+  CASE_STATEMENT(where, how, within, kLargeCode)                               \
+  CASE_STATEMENT(where, how, within, kLargeFixedArray)                         \
+  CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
+
+#define EMIT_COMMON_REFERENCE_PATTERNS(pseudo_space_number,                    \
+                                       space_number,                           \
+                                       offset_from_start)                      \
+  CASE_STATEMENT(kFromStart, kPlain, kStartOfObject, pseudo_space_number)      \
+  CASE_BODY(kFromStart, kPlain, kStartOfObject, space_number, offset_from_start)
+
+      // We generate 15 cases and bodies that process special tags that combine
+      // the raw data tag and the length into one byte.
 #define RAW_CASE(index, size)                                      \
-      case RAW_DATA_SERIALIZATION + index: {                       \
+      case kRawData + index: {                                     \
         byte* raw_data_out = reinterpret_cast<byte*>(current);     \
         source_->CopyRaw(raw_data_out, size);                      \
         current = reinterpret_cast<Object**>(raw_data_out + size); \
@@ -688,144 +825,77 @@
       }
       COMMON_RAW_LENGTHS(RAW_CASE)
 #undef RAW_CASE
-      case RAW_DATA_SERIALIZATION: {
+
+      // Deserialize a chunk of raw data that doesn't have one of the popular
+      // lengths.
+      case kRawData: {
         int size = source_->GetInt();
         byte* raw_data_out = reinterpret_cast<byte*>(current);
         source_->CopyRaw(raw_data_out, size);
         current = reinterpret_cast<Object**>(raw_data_out + size);
         break;
       }
-      case OBJECT_SERIALIZATION + NEW_SPACE: {
-        ReadObject(NEW_SPACE, Heap::new_space(), current);
-        if (space != NEW_SPACE) {
-          Heap::RecordWrite(address, static_cast<int>(
-              reinterpret_cast<Address>(current) - address));
-        }
-        current++;
-        break;
-      }
-      case OBJECT_SERIALIZATION + OLD_DATA_SPACE:
-        ReadObject(OLD_DATA_SPACE, Heap::old_data_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + OLD_POINTER_SPACE:
-        ReadObject(OLD_POINTER_SPACE, Heap::old_pointer_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + MAP_SPACE:
-        ReadObject(MAP_SPACE, Heap::map_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + CODE_SPACE:
-        ReadObject(CODE_SPACE, Heap::code_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + CELL_SPACE:
-        ReadObject(CELL_SPACE, Heap::cell_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + kLargeData:
-        ReadObject(kLargeData, Heap::lo_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + kLargeCode:
-        ReadObject(kLargeCode, Heap::lo_space(), current++);
-        break;
-      case OBJECT_SERIALIZATION + kLargeFixedArray:
-        ReadObject(kLargeFixedArray, Heap::lo_space(), current++);
-        break;
-      case CODE_OBJECT_SERIALIZATION + kLargeCode: {
-        Object* new_code_object = NULL;
-        ReadObject(kLargeCode, Heap::lo_space(), &new_code_object);
-        Code* code_object = reinterpret_cast<Code*>(new_code_object);
-        // Setting a branch/call to another code object from code.
-        Address location_of_branch_data = reinterpret_cast<Address>(current);
-        Assembler::set_target_at(location_of_branch_data,
-                                 code_object->instruction_start());
-        location_of_branch_data += Assembler::kCallTargetSize;
-        current = reinterpret_cast<Object**>(location_of_branch_data);
-        break;
-      }
-      case CODE_OBJECT_SERIALIZATION + CODE_SPACE: {
-        Object* new_code_object = NULL;
-        ReadObject(CODE_SPACE, Heap::code_space(), &new_code_object);
-        Code* code_object = reinterpret_cast<Code*>(new_code_object);
-        // Setting a branch/call to another code object from code.
-        Address location_of_branch_data = reinterpret_cast<Address>(current);
-        Assembler::set_target_at(location_of_branch_data,
-                                 code_object->instruction_start());
-        location_of_branch_data += Assembler::kCallTargetSize;
-        current = reinterpret_cast<Object**>(location_of_branch_data);
-        break;
-      }
-      ONE_CASE_PER_SPACE(BACKREF_SERIALIZATION) {
-        // Write a backreference to an object we unpacked earlier.
-        int backref_space = (data & kSpaceMask);
-        if (backref_space == NEW_SPACE && space != NEW_SPACE) {
-          Heap::RecordWrite(address, static_cast<int>(
-              reinterpret_cast<Address>(current) - address));
-        }
-        *current++ = GetAddressFromEnd(backref_space);
-        break;
-      }
-      ONE_CASE_PER_SPACE(REFERENCE_SERIALIZATION) {
-        // Write a reference to an object we unpacked earlier.
-        int reference_space = (data & kSpaceMask);
-        if (reference_space == NEW_SPACE && space != NEW_SPACE) {
-          Heap::RecordWrite(address, static_cast<int>(
-              reinterpret_cast<Address>(current) - address));
-        }
-        *current++ = GetAddressFromStart(reference_space);
-        break;
-      }
-#define COMMON_REFS_CASE(index, reference_space, address)                      \
-      case REFERENCE_SERIALIZATION + index: {                                  \
-        ASSERT(SpaceIsPaged(reference_space));                                 \
-        Address object_address =                                               \
-            pages_[reference_space][0] + (address << kObjectAlignmentBits);    \
-        *current++ = HeapObject::FromAddress(object_address);                  \
-        break;                                                                 \
-      }
-      COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
-#undef COMMON_REFS_CASE
-      ONE_CASE_PER_SPACE(CODE_BACKREF_SERIALIZATION) {
-        int backref_space = (data & kSpaceMask);
-        // Can't use Code::cast because heap is not set up yet and assertions
-        // will fail.
-        Code* code_object =
-            reinterpret_cast<Code*>(GetAddressFromEnd(backref_space));
-        // Setting a branch/call to previously decoded code object from code.
-        Address location_of_branch_data = reinterpret_cast<Address>(current);
-        Assembler::set_target_at(location_of_branch_data,
-                                 code_object->instruction_start());
-        location_of_branch_data += Assembler::kCallTargetSize;
-        current = reinterpret_cast<Object**>(location_of_branch_data);
-        break;
-      }
-      ONE_CASE_PER_SPACE(CODE_REFERENCE_SERIALIZATION) {
-        int backref_space = (data & kSpaceMask);
-        // Can't use Code::cast because heap is not set up yet and assertions
-        // will fail.
-        Code* code_object =
-            reinterpret_cast<Code*>(GetAddressFromStart(backref_space));
-        // Setting a branch/call to previously decoded code object from code.
-        Address location_of_branch_data = reinterpret_cast<Address>(current);
-        Assembler::set_target_at(location_of_branch_data,
-                                 code_object->instruction_start());
-        location_of_branch_data += Assembler::kCallTargetSize;
-        current = reinterpret_cast<Object**>(location_of_branch_data);
-        break;
-      }
-      case EXTERNAL_REFERENCE_SERIALIZATION: {
-        int reference_id = source_->GetInt();
-        Address address = external_reference_decoder_->Decode(reference_id);
-        *current++ = reinterpret_cast<Object*>(address);
-        break;
-      }
-      case EXTERNAL_BRANCH_TARGET_SERIALIZATION: {
-        int reference_id = source_->GetInt();
-        Address address = external_reference_decoder_->Decode(reference_id);
-        Address location_of_branch_data = reinterpret_cast<Address>(current);
-        Assembler::set_external_target_at(location_of_branch_data, address);
-        location_of_branch_data += Assembler::kExternalTargetSize;
-        current = reinterpret_cast<Object**>(location_of_branch_data);
-        break;
-      }
-      case START_NEW_PAGE_SERIALIZATION: {
+
+      // Deserialize a new object and write a pointer to it to the current
+      // object.
+      ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)
+      // Deserialize a new code object and write a pointer to its first
+      // instruction to the current code object.
+      ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction)
+      // Find a recently deserialized object using its offset from the current
+      // allocation point and write a pointer to it to the current object.
+      ALL_SPACES(kBackref, kPlain, kStartOfObject)
+      // Find a recently deserialized code object using its offset from the
+      // current allocation point and write a pointer to its first instruction
+      // to the current code object.
+      ALL_SPACES(kBackref, kFromCode, kFirstInstruction)
+      // Find an already deserialized object using its offset from the start
+      // and write a pointer to it to the current object.
+      ALL_SPACES(kFromStart, kPlain, kStartOfObject)
+      // Find an already deserialized code object using its offset from the
+      // start and write a pointer to its first instruction to the current code
+      // object.
+      ALL_SPACES(kFromStart, kFromCode, kFirstInstruction)
+      // Find an already deserialized object at one of the predetermined popular
+      // offsets from the start and write a pointer to it in the current object.
+      COMMON_REFERENCE_PATTERNS(EMIT_COMMON_REFERENCE_PATTERNS)
+      // Find an object in the roots array and write a pointer to it to the
+      // current object.
+      CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0)
+      CASE_BODY(kRootArray, kPlain, kStartOfObject, 0, kUnknownOffsetFromStart)
+      // Find an object in the partial snapshots cache and write a pointer to it
+      // to the current object.
+      CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0)
+      CASE_BODY(kPartialSnapshotCache,
+                kPlain,
+                kStartOfObject,
+                0,
+                kUnknownOffsetFromStart)
+      // Find an external reference and write a pointer to it to the current
+      // object.
+      CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0)
+      CASE_BODY(kExternalReference,
+                kPlain,
+                kStartOfObject,
+                0,
+                kUnknownOffsetFromStart)
+      // Find an external reference and write a pointer to it in the current
+      // code object.
+      CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0)
+      CASE_BODY(kExternalReference,
+                kFromCode,
+                kStartOfObject,
+                0,
+                kUnknownOffsetFromStart)
+
+#undef CASE_STATEMENT
+#undef CASE_BODY
+#undef ONE_PER_SPACE
+#undef ALL_SPACES
+#undef EMIT_COMMON_REFERENCE_PATTERNS
+#undef ASSIGN_DEST_SPACE
+
+      case kNewPage: {
         int space = source_->Get();
         pages_[space].Add(last_object_address_);
         if (space == CODE_SPACE) {
@@ -833,7 +903,8 @@
         }
         break;
       }
-      case NATIVES_STRING_RESOURCE: {
+
+      case kNativesStringResource: {
         int index = source_->Get();
         Vector<const char> source_vector = Natives::GetScriptSource(index);
         NativesExternalStringResource* resource =
@@ -841,21 +912,13 @@
         *current++ = reinterpret_cast<Object*>(resource);
         break;
       }
-      case ROOT_SERIALIZATION: {
-        int root_id = source_->GetInt();
-        *current++ = Heap::roots_address()[root_id];
-        break;
-      }
-      case PARTIAL_SNAPSHOT_CACHE_ENTRY: {
-        int cache_index = source_->GetInt();
-        *current++ = partial_snapshot_cache_[cache_index];
-        break;
-      }
-      case SYNCHRONIZE: {
+
+      case kSynchronize: {
         // If we get here then that indicates that you have a mismatch between
         // the number of GC roots when serializing and deserializing.
         UNREACHABLE();
       }
+
       default:
         UNREACHABLE();
     }
@@ -880,7 +943,7 @@
   int data = source_->Get();
   // If this assert fails then that indicates that you have a mismatch between
   // the number of GC roots when serializing and deserializing.
-  ASSERT_EQ(SYNCHRONIZE, data);
+  ASSERT_EQ(kSynchronize, data);
   do {
     int character = source_->Get();
     if (character == 0) break;
@@ -895,7 +958,7 @@
 
 
 void Serializer::Synchronize(const char* tag) {
-  sink_->Put(SYNCHRONIZE, tag);
+  sink_->Put(kSynchronize, tag);
   int character;
   do {
     character = *tag++;
@@ -957,13 +1020,13 @@
 void Serializer::VisitPointers(Object** start, Object** end) {
   for (Object** current = start; current < end; current++) {
     if ((*current)->IsSmi()) {
-      sink_->Put(RAW_DATA_SERIALIZATION, "RawData");
+      sink_->Put(kRawData, "RawData");
       sink_->PutInt(kPointerSize, "length");
       for (int i = 0; i < kPointerSize; i++) {
         sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
       }
     } else {
-      SerializeObject(*current, TAGGED_REPRESENTATION);
+      SerializeObject(*current, kPlain, kStartOfObject);
     }
   }
 }
@@ -1033,7 +1096,8 @@
 void Serializer::SerializeReferenceToPreviousObject(
     int space,
     int address,
-    ReferenceRepresentation reference_representation) {
+    HowToCode how_to_code,
+    WhereToPoint where_to_point) {
   int offset = CurrentAllocationAddress(space) - address;
   bool from_start = true;
   if (SpaceIsPaged(space)) {
@@ -1054,43 +1118,30 @@
   // If we are actually dealing with real offsets (and not a numbering of
   // all objects) then we should shift out the bits that are always 0.
   if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
-  // On some architectures references between code objects are encoded
-  // specially (as relative offsets).  Such references have their own
-  // special tags to simplify the deserializer.
-  if (reference_representation == CODE_TARGET_REPRESENTATION) {
-    if (from_start) {
-      sink_->Put(CODE_REFERENCE_SERIALIZATION + space, "RefCodeSer");
-      sink_->PutInt(address, "address");
-    } else {
-      sink_->Put(CODE_BACKREF_SERIALIZATION + space, "BackRefCodeSer");
+  if (from_start) {
+#define COMMON_REFS_CASE(pseudo_space, actual_space, offset)                   \
+    if (space == actual_space && address == offset &&                          \
+        how_to_code == kPlain && where_to_point == kStartOfObject) {           \
+      sink_->Put(kFromStart + how_to_code + where_to_point +                   \
+                 pseudo_space, "RefSer");                                      \
+    } else  /* NOLINT */
+    COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
+#undef COMMON_REFS_CASE
+    {  /* NOLINT */
+      sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer");
       sink_->PutInt(address, "address");
     }
   } else {
-    // Regular absolute references.
-    CHECK_EQ(TAGGED_REPRESENTATION, reference_representation);
-    if (from_start) {
-      // There are some common offsets that have their own specialized encoding.
-#define COMMON_REFS_CASE(tag, common_space, common_offset)               \
-      if (space == common_space && address == common_offset) {           \
-        sink_->PutSection(tag + REFERENCE_SERIALIZATION, "RefSer");      \
-      } else  /* NOLINT */
-      COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
-#undef COMMON_REFS_CASE
-      {  /* NOLINT */
-        sink_->Put(REFERENCE_SERIALIZATION + space, "RefSer");
-        sink_->PutInt(address, "address");
-      }
-    } else {
-      sink_->Put(BACKREF_SERIALIZATION + space, "BackRefSer");
-      sink_->PutInt(address, "address");
-    }
+    sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
+    sink_->PutInt(address, "address");
   }
 }
 
 
 void StartupSerializer::SerializeObject(
     Object* o,
-    ReferenceRepresentation reference_representation) {
+    HowToCode how_to_code,
+    WhereToPoint where_to_point) {
   CHECK(o->IsHeapObject());
   HeapObject* heap_object = HeapObject::cast(o);
 
@@ -1099,13 +1150,15 @@
     int address = address_mapper_.MappedTo(heap_object);
     SerializeReferenceToPreviousObject(space,
                                        address,
-                                       reference_representation);
+                                       how_to_code,
+                                       where_to_point);
   } else {
     // Object has not yet been serialized.  Serialize it here.
     ObjectSerializer object_serializer(this,
                                        heap_object,
                                        sink_,
-                                       reference_representation);
+                                       how_to_code,
+                                       where_to_point);
     object_serializer.Serialize();
   }
 }
@@ -1115,7 +1168,7 @@
   for (int i = partial_snapshot_cache_length_;
        i < kPartialSnapshotCacheCapacity;
        i++) {
-    sink_->Put(ROOT_SERIALIZATION, "RootSerialization");
+    sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization");
     sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index");
   }
   Heap::IterateWeakRoots(this, VISIT_ALL);
@@ -1124,20 +1177,22 @@
 
 void PartialSerializer::SerializeObject(
     Object* o,
-    ReferenceRepresentation reference_representation) {
+    HowToCode how_to_code,
+    WhereToPoint where_to_point) {
   CHECK(o->IsHeapObject());
   HeapObject* heap_object = HeapObject::cast(o);
 
   int root_index;
   if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
-    sink_->Put(ROOT_SERIALIZATION, "RootSerialization");
+    sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
     sink_->PutInt(root_index, "root_index");
     return;
   }
 
   if (ShouldBeInThePartialSnapshotCache(heap_object)) {
     int cache_index = PartialSnapshotCacheIndex(heap_object);
-    sink_->Put(PARTIAL_SNAPSHOT_CACHE_ENTRY, "PartialSnapshotCache");
+    sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point,
+               "PartialSnapshotCache");
     sink_->PutInt(cache_index, "partial_snapshot_cache_index");
     return;
   }
@@ -1155,13 +1210,15 @@
     int address = address_mapper_.MappedTo(heap_object);
     SerializeReferenceToPreviousObject(space,
                                        address,
-                                       reference_representation);
+                                       how_to_code,
+                                       where_to_point);
   } else {
     // Object has not yet been serialized.  Serialize it here.
     ObjectSerializer serializer(this,
                                 heap_object,
                                 sink_,
-                                reference_representation);
+                                how_to_code,
+                                where_to_point);
     serializer.Serialize();
   }
 }
@@ -1171,12 +1228,8 @@
   int space = Serializer::SpaceOfObject(object_);
   int size = object_->Size();
 
-  if (reference_representation_ == TAGGED_REPRESENTATION) {
-    sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization");
-  } else {
-    CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_);
-    sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization");
-  }
+  sink_->Put(kNewObject + reference_representation_ + space,
+             "ObjectSerialization");
   sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
 
   LOG(SnapshotPositionEvent(object_->address(), sink_->Position()));
@@ -1186,12 +1239,12 @@
   int offset = serializer_->Allocate(space, size, &start_new_page);
   serializer_->address_mapper()->AddMapping(object_, offset);
   if (start_new_page) {
-    sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage");
+    sink_->Put(kNewPage, "NewPage");
     sink_->PutSection(space, "NewPageSpace");
   }
 
   // Serialize the map (first word of the object).
-  serializer_->SerializeObject(object_->map(), TAGGED_REPRESENTATION);
+  serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject);
 
   // Serialize the rest of the object.
   CHECK_EQ(0, bytes_processed_so_far_);
@@ -1209,7 +1262,7 @@
     if (current < end) OutputRawData(reinterpret_cast<Address>(current));
 
     while (current < end && !(*current)->IsSmi()) {
-      serializer_->SerializeObject(*current, TAGGED_REPRESENTATION);
+      serializer_->SerializeObject(*current, kPlain, kStartOfObject);
       bytes_processed_so_far_ += kPointerSize;
       current++;
     }
@@ -1223,7 +1276,7 @@
   OutputRawData(references_start);
 
   for (Address* current = start; current < end; current++) {
-    sink_->Put(EXTERNAL_REFERENCE_SERIALIZATION, "ExternalReference");
+    sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef");
     int reference_id = serializer_->EncodeExternalReference(*current);
     sink_->PutInt(reference_id, "reference id");
   }
@@ -1237,9 +1290,16 @@
   Address target = rinfo->target_address();
   uint32_t encoding = serializer_->EncodeExternalReference(target);
   CHECK(target == NULL ? encoding == 0 : encoding != 0);
-  sink_->Put(EXTERNAL_BRANCH_TARGET_SERIALIZATION, "ExternalReference");
+  int representation;
+  // Can't use a ternary operator because of gcc.
+  if (rinfo->IsCodedSpecially()) {
+    representation = kStartOfObject + kFromCode;
+  } else {
+    representation = kStartOfObject + kPlain;
+  }
+  sink_->Put(kExternalReference + representation, "ExternalReference");
   sink_->PutInt(encoding, "reference id");
-  bytes_processed_so_far_ += Assembler::kExternalTargetSize;
+  bytes_processed_so_far_ += rinfo->target_address_size();
 }
 
 
@@ -1248,8 +1308,8 @@
   Address target_start = rinfo->target_address_address();
   OutputRawData(target_start);
   Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
-  serializer_->SerializeObject(target, CODE_TARGET_REPRESENTATION);
-  bytes_processed_so_far_ += Assembler::kCallTargetSize;
+  serializer_->SerializeObject(target, kFromCode, kFirstInstruction);
+  bytes_processed_so_far_ += rinfo->target_address_size();
 }
 
 
@@ -1264,7 +1324,7 @@
       typedef v8::String::ExternalAsciiStringResource Resource;
       Resource* resource = string->resource();
       if (resource == *resource_pointer) {
-        sink_->Put(NATIVES_STRING_RESOURCE, "NativesStringResource");
+        sink_->Put(kNativesStringResource, "NativesStringResource");
         sink_->PutSection(i, "NativesStringResourceEnd");
         bytes_processed_so_far_ += sizeof(resource);
         return;
@@ -1288,12 +1348,12 @@
     Address base = object_start + bytes_processed_so_far_;
 #define RAW_CASE(index, length)                                                \
     if (skipped == length) {                                                   \
-      sink_->PutSection(RAW_DATA_SERIALIZATION + index, "RawDataFixed");       \
+      sink_->PutSection(kRawData + index, "RawDataFixed");                     \
     } else  /* NOLINT */
     COMMON_RAW_LENGTHS(RAW_CASE)
 #undef RAW_CASE
     {  /* NOLINT */
-      sink_->Put(RAW_DATA_SERIALIZATION, "RawData");
+      sink_->Put(kRawData, "RawData");
       sink_->PutInt(skipped, "length");
     }
     for (int i = 0; i < skipped; i++) {