Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/snapshot/serializer.cc b/src/snapshot/serializer.cc
index f6f2200..b6a75ff 100644
--- a/src/snapshot/serializer.cc
+++ b/src/snapshot/serializer.cc
@@ -10,9 +10,8 @@
namespace v8 {
namespace internal {
-Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
+Serializer::Serializer(Isolate* isolate)
: isolate_(isolate),
- sink_(sink),
external_reference_encoder_(isolate),
root_index_map_(isolate),
recursion_depth_(0),
@@ -90,10 +89,10 @@
void Serializer::SerializeDeferredObjects() {
while (deferred_objects_.length() > 0) {
HeapObject* obj = deferred_objects_.RemoveLast();
- ObjectSerializer obj_serializer(this, obj, sink_, kPlain, kStartOfObject);
+ ObjectSerializer obj_serializer(this, obj, &sink_, kPlain, kStartOfObject);
obj_serializer.SerializeDeferred();
}
- sink_->Put(kSynchronize, "Finished with deferred objects");
+ sink_.Put(kSynchronize, "Finished with deferred objects");
}
void Serializer::VisitPointers(Object** start, Object** end) {
@@ -141,62 +140,61 @@
}
#endif // DEBUG
-bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
- WhereToPoint where_to_point, int skip) {
- if (how_to_code == kPlain && where_to_point == kStartOfObject) {
- // Encode a reference to a hot object by its index in the working set.
- int index = hot_objects_.Find(obj);
- if (index != HotObjectsList::kNotFound) {
- DCHECK(index >= 0 && index < kNumberOfHotObjects);
- if (FLAG_trace_serializer) {
- PrintF(" Encoding hot object %d:", index);
- obj->ShortPrint();
- PrintF("\n");
- }
- if (skip != 0) {
- sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
- sink_->PutInt(skip, "HotObjectSkipDistance");
- } else {
- sink_->Put(kHotObject + index, "HotObject");
- }
- return true;
- }
+bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code,
+ WhereToPoint where_to_point, int skip) {
+ if (how_to_code != kPlain || where_to_point != kStartOfObject) return false;
+ // Encode a reference to a hot object by its index in the working set.
+ int index = hot_objects_.Find(obj);
+ if (index == HotObjectsList::kNotFound) return false;
+ DCHECK(index >= 0 && index < kNumberOfHotObjects);
+ if (FLAG_trace_serializer) {
+ PrintF(" Encoding hot object %d:", index);
+ obj->ShortPrint();
+ PrintF("\n");
}
+ if (skip != 0) {
+ sink_.Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
+ sink_.PutInt(skip, "HotObjectSkipDistance");
+ } else {
+ sink_.Put(kHotObject + index, "HotObject");
+ }
+ return true;
+}
+bool Serializer::SerializeBackReference(HeapObject* obj, HowToCode how_to_code,
+ WhereToPoint where_to_point, int skip) {
SerializerReference reference = reference_map_.Lookup(obj);
- if (reference.is_valid()) {
- // Encode the location of an already deserialized object in order to write
- // its location into a later object. We can encode the location as an
- // offset fromthe start of the deserialized objects or as an offset
- // backwards from thecurrent allocation pointer.
- if (reference.is_attached_reference()) {
- FlushSkip(skip);
- if (FLAG_trace_serializer) {
- PrintF(" Encoding attached reference %d\n",
- reference.attached_reference_index());
- }
- PutAttachedReference(reference, how_to_code, where_to_point);
- } else {
- DCHECK(reference.is_back_reference());
- if (FLAG_trace_serializer) {
- PrintF(" Encoding back reference to: ");
- obj->ShortPrint();
- PrintF("\n");
- }
-
- PutAlignmentPrefix(obj);
- AllocationSpace space = reference.space();
- if (skip == 0) {
- sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef");
- } else {
- sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
- "BackRefWithSkip");
- sink_->PutInt(skip, "BackRefSkipDistance");
- }
- PutBackReference(obj, reference);
+ if (!reference.is_valid()) return false;
+ // Encode the location of an already deserialized object in order to write
+ // its location into a later object. We can encode the location as an
+ // offset fromthe start of the deserialized objects or as an offset
+ // backwards from thecurrent allocation pointer.
+ if (reference.is_attached_reference()) {
+ FlushSkip(skip);
+ if (FLAG_trace_serializer) {
+ PrintF(" Encoding attached reference %d\n",
+ reference.attached_reference_index());
}
- return true;
+ PutAttachedReference(reference, how_to_code, where_to_point);
+ } else {
+ DCHECK(reference.is_back_reference());
+ if (FLAG_trace_serializer) {
+ PrintF(" Encoding back reference to: ");
+ obj->ShortPrint();
+ PrintF("\n");
+ }
+
+ PutAlignmentPrefix(obj);
+ AllocationSpace space = reference.space();
+ if (skip == 0) {
+ sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef");
+ } else {
+ sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space,
+ "BackRefWithSkip");
+ sink_.PutInt(skip, "BackRefSkipDistance");
+ }
+ PutBackReference(obj, reference);
}
- return false;
+ return true;
}
void Serializer::PutRoot(int root_index, HeapObject* object,
@@ -213,28 +211,29 @@
root_index < kNumberOfRootArrayConstants &&
!isolate()->heap()->InNewSpace(object)) {
if (skip == 0) {
- sink_->Put(kRootArrayConstants + root_index, "RootConstant");
+ sink_.Put(kRootArrayConstants + root_index, "RootConstant");
} else {
- sink_->Put(kRootArrayConstantsWithSkip + root_index, "RootConstant");
- sink_->PutInt(skip, "SkipInPutRoot");
+ sink_.Put(kRootArrayConstantsWithSkip + root_index, "RootConstant");
+ sink_.PutInt(skip, "SkipInPutRoot");
}
} else {
FlushSkip(skip);
- sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
- sink_->PutInt(root_index, "root_index");
+ sink_.Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
+ sink_.PutInt(root_index, "root_index");
+ hot_objects_.Add(object);
}
}
void Serializer::PutSmi(Smi* smi) {
- sink_->Put(kOnePointerRawData, "Smi");
+ sink_.Put(kOnePointerRawData, "Smi");
byte* bytes = reinterpret_cast<byte*>(&smi);
- for (int i = 0; i < kPointerSize; i++) sink_->Put(bytes[i], "Byte");
+ for (int i = 0; i < kPointerSize; i++) sink_.Put(bytes[i], "Byte");
}
void Serializer::PutBackReference(HeapObject* object,
SerializerReference reference) {
DCHECK(BackReferenceIsAlreadyAllocated(reference));
- sink_->PutInt(reference.back_reference(), "BackRefValue");
+ sink_.PutInt(reference.back_reference(), "BackRefValue");
hot_objects_.Add(object);
}
@@ -245,8 +244,8 @@
DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
(how_to_code == kPlain && where_to_point == kInnerPointer) ||
(how_to_code == kFromCode && where_to_point == kInnerPointer));
- sink_->Put(kAttachedReference + how_to_code + where_to_point, "AttachedRef");
- sink_->PutInt(reference.attached_reference_index(), "AttachedRefIndex");
+ sink_.Put(kAttachedReference + how_to_code + where_to_point, "AttachedRef");
+ sink_.PutInt(reference.attached_reference_index(), "AttachedRefIndex");
}
int Serializer::PutAlignmentPrefix(HeapObject* object) {
@@ -254,7 +253,7 @@
if (alignment != kWordAligned) {
DCHECK(1 <= alignment && alignment <= 3);
byte prefix = (kAlignmentPrefix - 1) + alignment;
- sink_->Put(prefix, "Alignment");
+ sink_.Put(prefix, "Alignment");
return Heap::GetMaximumFillToAlign(alignment);
}
return 0;
@@ -274,8 +273,8 @@
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, "NextChunk");
- sink_->Put(space, "NextChunkSpace");
+ sink_.Put(kNextChunk, "NextChunk");
+ sink_.Put(space, "NextChunkSpace");
completed_chunks_[space].Add(pending_chunk_[space]);
pending_chunk_[space] = 0;
new_chunk_size = size;
@@ -290,11 +289,11 @@
// The non-branching GetInt will read up to 3 bytes too far, so we need
// to pad the snapshot to make sure we don't read over the end.
for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) {
- sink_->Put(kNop, "Padding");
+ sink_.Put(kNop, "Padding");
}
// Pad up to pointer size for checksum.
- while (!IsAligned(sink_->Position(), kPointerAlignment)) {
- sink_->Put(kNop, "Padding");
+ while (!IsAligned(sink_.Position(), kPointerAlignment)) {
+ sink_.Put(kNop, "Padding");
}
}
@@ -668,9 +667,10 @@
int builtin_count,
v8::String::ExternalOneByteStringResource** resource_pointer,
FixedArray* source_cache, int resource_index) {
+ Isolate* isolate = serializer_->isolate();
for (int i = 0; i < builtin_count; i++) {
Object* source = source_cache->get(i);
- if (!source->IsUndefined()) {
+ if (!source->IsUndefined(isolate)) {
ExternalOneByteString* string = ExternalOneByteString::cast(source);
typedef v8::String::ExternalOneByteStringResource Resource;
const Resource* resource = string->resource();
@@ -687,6 +687,9 @@
void Serializer::ObjectSerializer::VisitExternalOneByteString(
v8::String::ExternalOneByteStringResource** resource_pointer) {
+ DCHECK_EQ(serializer_->isolate()->heap()->native_source_string_map(),
+ object_->map());
+ DCHECK(ExternalOneByteString::cast(object_)->is_short());
Address references_start = reinterpret_cast<Address>(resource_pointer);
OutputRawData(references_start);
if (SerializeExternalNativeSourceString(
@@ -707,25 +710,27 @@
}
Address Serializer::ObjectSerializer::PrepareCode() {
- // To make snapshots reproducible, we make a copy of the code object
- // and wipe all pointers in the copy, which we then serialize.
- Code* original = Code::cast(object_);
- Code* code = serializer_->CopyCode(original);
+ Code* code = Code::cast(object_);
+ if (FLAG_predictable) {
+ // To make snapshots reproducible, we make a copy of the code object
+ // and wipe all pointers in the copy, which we then serialize.
+ code = serializer_->CopyCode(code);
+ int mode_mask = RelocInfo::kCodeTargetMask |
+ RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
+ RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
+ RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
+ RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
+ RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
+ for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
+ RelocInfo* rinfo = it.rinfo();
+ rinfo->WipeOut();
+ }
+ // We need to wipe out the header fields *after* wiping out the
+ // relocations, because some of these fields are needed for the latter.
+ code->WipeOutHeader();
+ }
// Code age headers are not serializable.
code->MakeYoung(serializer_->isolate());
- int mode_mask = RelocInfo::kCodeTargetMask |
- RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
- RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
- RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
- RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
- RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
- for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
- RelocInfo* rinfo = it.rinfo();
- rinfo->WipeOut();
- }
- // We need to wipe out the header fields *after* wiping out the
- // relocations, because some of these fields are needed for the latter.
- code->WipeOutHeader();
return code->address();
}