Index: src/snapshot/serialize.cc |
diff --git a/src/snapshot/serialize.cc b/src/snapshot/serialize.cc |
index 8b382c09fb1a3c047a1c22f02dd2dc3ad9703b42..026d60221dcc8fe0e22f134e3c9a861dca8279f9 100644 |
--- a/src/snapshot/serialize.cc |
+++ b/src/snapshot/serialize.cc |
@@ -753,6 +753,8 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { |
new_code_objects_.Add(Code::cast(obj)); |
} |
} |
+ // Check alignment. |
+ DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment())); |
return obj; |
} |
@@ -769,8 +771,14 @@ HeapObject* Deserializer::GetBackReferencedObject(int space) { |
uint32_t chunk_index = back_reference.chunk_index(); |
DCHECK_LE(chunk_index, current_chunk_[space]); |
uint32_t chunk_offset = back_reference.chunk_offset(); |
- obj = HeapObject::FromAddress(reservations_[space][chunk_index].start + |
- chunk_offset); |
+ Address address = reservations_[space][chunk_index].start + chunk_offset; |
+ if (next_alignment_ != kWordAligned) { |
+ int padding = Heap::GetFillToAlign(address, next_alignment_); |
+ next_alignment_ = kWordAligned; |
+ DCHECK(padding == 0 || HeapObject::FromAddress(address)->IsFiller()); |
+ address += padding; |
+ } |
+ obj = HeapObject::FromAddress(address); |
} |
if (deserializing_user_code() && obj->IsInternalizedString()) { |
obj = String::cast(obj)->GetForwardedInternalizedString(); |
@@ -788,22 +796,25 @@ HeapObject* Deserializer::GetBackReferencedObject(int space) { |
void Deserializer::ReadObject(int space_number, Object** write_back) { |
Address address; |
HeapObject* obj; |
- int next_int = source_.GetInt(); |
- |
- bool double_align = false; |
-#ifndef V8_HOST_ARCH_64_BIT |
- double_align = next_int == kDoubleAlignmentSentinel; |
- if (double_align) next_int = source_.GetInt(); |
-#endif |
- |
- DCHECK_NE(kDoubleAlignmentSentinel, next_int); |
- int size = next_int << kObjectAlignmentBits; |
- int reserved_size = size + (double_align ? kPointerSize : 0); |
- address = Allocate(space_number, reserved_size); |
- obj = HeapObject::FromAddress(address); |
- if (double_align) { |
- obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size); |
+ int size = source_.GetInt() << kObjectAlignmentBits; |
+ |
+ if (next_alignment_ != kWordAligned) { |
+ int reserved = size + Heap::GetMaximumFillToAlign(next_alignment_); |
+ address = Allocate(space_number, reserved); |
+ obj = HeapObject::FromAddress(address); |
+ // If one of the following assertions fails, then we are deserializing an |
+ // aligned object when the filler maps have not been deserialized yet. |
+ // We require filler maps as padding to align the object. |
+ Heap* heap = isolate_->heap(); |
+ DCHECK(heap->free_space_map()->IsMap()); |
+ DCHECK(heap->one_pointer_filler_map()->IsMap()); |
+ DCHECK(heap->two_pointer_filler_map()->IsMap()); |
+ obj = heap->AlignWithFiller(obj, size, reserved, next_alignment_); |
address = obj->address(); |
+ next_alignment_ = kWordAligned; |
+ } else { |
+ address = Allocate(space_number, size); |
+ obj = HeapObject::FromAddress(address); |
} |
isolate_->heap()->OnAllocationEvent(obj, size); |
@@ -998,14 +1009,17 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space, |
FOUR_CASES(byte_code + 8) \ |
FOUR_CASES(byte_code + 12) |
+#define SINGLE_CASE(where, how, within, space) \ |
+ CASE_STATEMENT(where, how, within, space) \ |
+ CASE_BODY(where, how, within, space) |
+ |
// Deserialize a new object and write a pointer to it to the current |
// object. |
ALL_SPACES(kNewObject, kPlain, kStartOfObject) |
// Support for direct instruction pointers in functions. It's an inner |
// pointer because it points at the entry point, not at the start of the |
// code object. |
- CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
- CASE_BODY(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
+ SINGLE_CASE(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
// Deserialize a new code object and write a pointer to its first |
// instruction to the current code object. |
ALL_SPACES(kNewObject, kFromCode, kInnerPointer) |
@@ -1036,45 +1050,33 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space, |
ALL_SPACES(kBackrefWithSkip, kPlain, kInnerPointer) |
// 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) |
+ SINGLE_CASE(kRootArray, kPlain, kStartOfObject, 0) |
#if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ |
defined(V8_TARGET_ARCH_PPC) || V8_EMBEDDED_CONSTANT_POOL |
// Find an object in the roots array and write a pointer to it to in code. |
- CASE_STATEMENT(kRootArray, kFromCode, kStartOfObject, 0) |
- CASE_BODY(kRootArray, kFromCode, kStartOfObject, 0) |
+ SINGLE_CASE(kRootArray, kFromCode, kStartOfObject, 0) |
#endif |
// 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) |
+ SINGLE_CASE(kPartialSnapshotCache, kPlain, kStartOfObject, 0) |
// Find an code entry in the partial snapshots cache and |
// write a pointer to it to the current object. |
- CASE_STATEMENT(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
- CASE_BODY(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
+ SINGLE_CASE(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
// 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) |
+ SINGLE_CASE(kExternalReference, kPlain, kStartOfObject, 0) |
// 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) |
+ SINGLE_CASE(kExternalReference, kFromCode, kStartOfObject, 0) |
// Find an object in the attached references and write a pointer to it to |
// the current object. |
- CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0) |
- CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0) |
- CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0) |
- CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0) |
- CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0) |
- CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0) |
+ SINGLE_CASE(kAttachedReference, kPlain, kStartOfObject, 0) |
+ SINGLE_CASE(kAttachedReference, kPlain, kInnerPointer, 0) |
+ SINGLE_CASE(kAttachedReference, kFromCode, kInnerPointer, 0) |
// Find a builtin and write a pointer to it to the current object. |
- CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0) |
- CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0) |
- CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0) |
- CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0) |
- CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) |
- CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) |
+ SINGLE_CASE(kBuiltin, kPlain, kStartOfObject, 0) |
+ SINGLE_CASE(kBuiltin, kPlain, kInnerPointer, 0) |
+ SINGLE_CASE(kBuiltin, kFromCode, kInnerPointer, 0) |
#undef CASE_STATEMENT |
#undef CASE_BODY |
@@ -1169,6 +1171,15 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space, |
break; |
} |
+ case kAlignmentPrefix: |
+ case kAlignmentPrefix + 1: |
+ case kAlignmentPrefix + 2: { |
+ DCHECK_EQ(kWordAligned, next_alignment_); |
+ next_alignment_ = |
+ static_cast<AllocationAlignment>(data - (kAlignmentPrefix - 1)); |
+ break; |
+ } |
+ |
STATIC_ASSERT(kNumberOfRootArrayConstants == Heap::kOldSpaceRoots); |
STATIC_ASSERT(kNumberOfRootArrayConstants == 32); |
SIXTEEN_CASES(kRootArrayConstantsWithSkip) |
@@ -1235,6 +1246,7 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space, |
#undef SIXTEEN_CASES |
#undef FOUR_CASES |
+#undef SINGLE_CASE |
default: |
CHECK(false); |
@@ -1562,6 +1574,7 @@ bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, |
PrintF("\n"); |
} |
+ PutAlignmentPrefix(obj); |
AllocationSpace space = back_reference.space(); |
if (skip == 0) { |
sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef"); |
@@ -1655,6 +1668,18 @@ void Serializer::PutBackReference(HeapObject* object, BackReference reference) { |
} |
+int Serializer::PutAlignmentPrefix(HeapObject* object) { |
+ AllocationAlignment alignment = object->RequiredAlignment(); |
+ if (alignment != kWordAligned) { |
+ DCHECK(1 <= alignment && alignment <= 3); |
+ byte prefix = (kAlignmentPrefix - 1) + alignment; |
+ sink_->Put(prefix, "Alignment"); |
+ return Heap::GetMaximumFillToAlign(alignment); |
+ } |
+ return 0; |
+} |
+ |
+ |
void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
WhereToPoint where_to_point, int skip) { |
if (obj->IsMap()) { |
@@ -1736,21 +1761,10 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
} |
back_reference = serializer_->AllocateLargeObject(size); |
} else { |
- bool needs_double_align = false; |
- // TODO(bbudge): Generalize to other alignment constraints. |
- if (object_->RequiredAlignment() == kDoubleAligned) { |
- // Add wriggle room for double alignment padding. |
- back_reference = serializer_->Allocate(space, size + kPointerSize); |
- needs_double_align = true; |
- } else { |
- back_reference = serializer_->Allocate(space, size); |
- } |
+ int fill = serializer_->PutAlignmentPrefix(object_); |
+ back_reference = serializer_->Allocate(space, size + fill); |
sink_->Put(kNewObject + reference_representation_ + space, "NewObject"); |
- if (needs_double_align) |
- sink_->PutInt(kDoubleAlignmentSentinel, "DoubleAlignSentinel"); |
- int encoded_size = size >> kObjectAlignmentBits; |
- DCHECK_NE(kDoubleAlignmentSentinel, encoded_size); |
- sink_->PutInt(encoded_size, "ObjectSizeInWords"); |
+ sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); |
} |
#ifdef OBJECT_PRINT |