Commit bde4dc8e authored by Vyacheslav Chigrin's avatar Vyacheslav Chigrin Committed by Commit Bot

Fix serializing objects that may require non-world aligning.

We must ensure required root objects will be filled when such
objects will be deserialized.

Change-Id: I25136d31cb2e0c0a69a51c5635192f17bbe2a9ba
Reviewed-on: https://chromium-review.googlesource.com/579768
Commit-Queue: Vyacheslav Chigrin <vchigrin@yandex-team.ru>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46944}
parent be915fd7
......@@ -100,6 +100,8 @@ void Serializer::SerializeDeferredObjects() {
sink_.Put(kSynchronize, "Finished with deferred objects");
}
bool Serializer::MustBeDeferred(HeapObject* object) { return false; }
void Serializer::VisitRootPointers(Root root, Object** start, Object** end) {
for (Object** current = start; current < end; current++) {
if ((*current)->IsSmi()) {
......@@ -558,7 +560,8 @@ void Serializer::ObjectSerializer::SerializeContent() {
RecursionScope recursion(serializer_);
// Objects that are immediately post processed during deserialization
// cannot be deferred, since post processing requires the object content.
if (recursion.ExceedsMaximum() && CanBeDeferred(object_)) {
if ((recursion.ExceedsMaximum() && CanBeDeferred(object_)) ||
serializer_->MustBeDeferred(object_)) {
serializer_->QueueDeferredObject(object_);
sink_->Put(kDeferred, "Deferring object content");
return;
......
......@@ -156,6 +156,8 @@ class Serializer : public SerializerDeserializer {
virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) = 0;
virtual bool MustBeDeferred(HeapObject* object);
void VisitRootPointers(Root root, Object** start, Object** end) override;
void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
......
......@@ -196,5 +196,21 @@ void StartupSerializer::CheckRehashability(HeapObject* table) {
can_be_rehashed_ = false;
}
bool StartupSerializer::MustBeDeferred(HeapObject* object) {
if (root_has_been_serialized_.test(Heap::kFreeSpaceMapRootIndex) &&
root_has_been_serialized_.test(Heap::kOnePointerFillerMapRootIndex) &&
root_has_been_serialized_.test(Heap::kTwoPointerFillerMapRootIndex)) {
// All required root objects are serialized, so any aligned objects can
// be saved without problems.
return false;
}
// Just defer everything except of Map objects until all required roots are
// serialized. Some objects may have special alignment requirements, that may
// not be fulfilled during deserialization until few first root objects are
// serialized. But we must serialize Map objects since deserializer checks
// that these root objects are indeed Maps.
return !object->IsMap();
}
} // namespace internal
} // namespace v8
......@@ -63,6 +63,7 @@ class StartupSerializer : public Serializer {
void SerializeObject(HeapObject* o, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) override;
void Synchronize(VisitorSynchronization::SyncTag tag) override;
bool MustBeDeferred(HeapObject* object) override;
// Some roots should not be serialized, because their actual value depends on
// absolute addresses and they are reset after deserialization, anyway.
......
......@@ -184,6 +184,54 @@ UNINITIALIZED_TEST(StartupSerializerOnce) {
isolate->Dispose();
}
UNINITIALIZED_TEST(StartupSerializerRootMapDependencies) {
DisableAlwaysOpt();
v8::SnapshotCreator snapshot_creator;
v8::Isolate* isolate = snapshot_creator.GetIsolate();
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
Isolate* internal_isolate = reinterpret_cast<Isolate*>(isolate);
// Here is interesting retaining path:
// - FreeSpaceMap
// - Map for Map types itself
// - NullValue
// - Internalized one byte string
// - Map for Internalized one byte string
// - WeakCell
// - TheHoleValue
// - HeapNumber
// HeapNumber objects require kDoubleUnaligned on 32-bit
// platforms. So, without special measures we're risking to serialize
// object, requiring alignment before FreeSpaceMap is fully serialized.
v8::internal::Handle<Map> map(
internal_isolate->heap()->one_byte_internalized_string_map());
Map::WeakCellForMap(map);
// Need to avoid DCHECKs inside SnapshotCreator.
snapshot_creator.SetDefaultContext(v8::Context::New(isolate));
}
v8::StartupData startup_data = snapshot_creator.CreateBlob(
v8::SnapshotCreator::FunctionCodeHandling::kKeep);
v8::Isolate::CreateParams params;
params.snapshot_blob = &startup_data;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
isolate = v8::Isolate::New(params);
{
v8::HandleScope handle_scope(isolate);
v8::Isolate::Scope isolate_scope(isolate);
v8::Local<v8::Context> env = v8::Context::New(isolate);
env->Enter();
SanityCheck(isolate);
}
isolate->Dispose();
delete[] startup_data.data;
}
UNINITIALIZED_TEST(StartupSerializerTwice) {
DisableAlwaysOpt();
v8::Isolate* isolate = TestIsolate::NewInitialized(true);
......
......@@ -164,10 +164,10 @@ KNOWN_MAPS = {
0x02259: (131, "MetaMap"),
0x022b1: (130, "NullMap"),
0x02309: (170, "FixedArrayMap"),
0x02361: (8, "OneByteInternalizedStringMap"),
0x023b9: (148, "OnePointerFillerMap"),
0x02411: (148, "TwoPointerFillerMap"),
0x02469: (130, "UninitializedMap"),
0x02361: (148, "OnePointerFillerMap"),
0x023b9: (148, "TwoPointerFillerMap"),
0x02411: (130, "UninitializedMap"),
0x02469: (8, "OneByteInternalizedStringMap"),
0x024c1: (130, "UndefinedMap"),
0x02519: (129, "HeapNumberMap"),
0x02571: (130, "TheHoleMap"),
......@@ -275,46 +275,46 @@ KNOWN_OBJECTS = {
("OLD_SPACE", 0x02201): "NullValue",
("OLD_SPACE", 0x02231): "EmptyDescriptorArray",
("OLD_SPACE", 0x02241): "EmptyFixedArray",
("OLD_SPACE", 0x02291): "UninitializedValue",
("OLD_SPACE", 0x02311): "UndefinedValue",
("OLD_SPACE", 0x02341): "NanValue",
("OLD_SPACE", 0x02351): "TheHoleValue",
("OLD_SPACE", 0x023a1): "HoleNanValue",
("OLD_SPACE", 0x023b1): "TrueValue",
("OLD_SPACE", 0x02421): "FalseValue",
("OLD_SPACE", 0x02471): "empty_string",
("OLD_SPACE", 0x02489): "EmptyScopeInfo",
("OLD_SPACE", 0x02499): "ArgumentsMarker",
("OLD_SPACE", 0x024f1): "Exception",
("OLD_SPACE", 0x02549): "TerminationException",
("OLD_SPACE", 0x025a9): "OptimizedOut",
("OLD_SPACE", 0x02601): "StaleRegister",
("OLD_SPACE", 0x02659): "EmptyByteArray",
("OLD_SPACE", 0x02669): "EmptyFixedUint8Array",
("OLD_SPACE", 0x02689): "EmptyFixedInt8Array",
("OLD_SPACE", 0x026a9): "EmptyFixedUint16Array",
("OLD_SPACE", 0x026c9): "EmptyFixedInt16Array",
("OLD_SPACE", 0x026e9): "EmptyFixedUint32Array",
("OLD_SPACE", 0x02709): "EmptyFixedInt32Array",
("OLD_SPACE", 0x02729): "EmptyFixedFloat32Array",
("OLD_SPACE", 0x02749): "EmptyFixedFloat64Array",
("OLD_SPACE", 0x02769): "EmptyFixedUint8ClampedArray",
("OLD_SPACE", 0x02789): "EmptyScript",
("OLD_SPACE", 0x02809): "UndefinedCell",
("OLD_SPACE", 0x02819): "EmptySloppyArgumentsElements",
("OLD_SPACE", 0x02839): "EmptySlowElementDictionary",
("OLD_SPACE", 0x02881): "EmptyPropertyCell",
("OLD_SPACE", 0x028a9): "EmptyWeakCell",
("OLD_SPACE", 0x028b9): "ArrayProtector",
("OLD_SPACE", 0x028e1): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x028f1): "SpeciesProtector",
("OLD_SPACE", 0x02919): "StringLengthProtector",
("OLD_SPACE", 0x02941): "FastArrayIterationProtector",
("OLD_SPACE", 0x02951): "ArrayIteratorProtector",
("OLD_SPACE", 0x02979): "ArrayBufferNeuteringProtector",
("OLD_SPACE", 0x029a1): "InfinityValue",
("OLD_SPACE", 0x029b1): "MinusZeroValue",
("OLD_SPACE", 0x029c1): "MinusInfinityValue",
("OLD_SPACE", 0x02251): "UninitializedValue",
("OLD_SPACE", 0x022d1): "UndefinedValue",
("OLD_SPACE", 0x02301): "NanValue",
("OLD_SPACE", 0x02311): "TheHoleValue",
("OLD_SPACE", 0x02361): "HoleNanValue",
("OLD_SPACE", 0x02371): "TrueValue",
("OLD_SPACE", 0x023e1): "FalseValue",
("OLD_SPACE", 0x02431): "empty_string",
("OLD_SPACE", 0x02449): "EmptyScopeInfo",
("OLD_SPACE", 0x02459): "ArgumentsMarker",
("OLD_SPACE", 0x024b1): "Exception",
("OLD_SPACE", 0x02509): "TerminationException",
("OLD_SPACE", 0x02569): "OptimizedOut",
("OLD_SPACE", 0x025c1): "StaleRegister",
("OLD_SPACE", 0x02619): "EmptyByteArray",
("OLD_SPACE", 0x02629): "EmptyFixedUint8Array",
("OLD_SPACE", 0x02649): "EmptyFixedInt8Array",
("OLD_SPACE", 0x02669): "EmptyFixedUint16Array",
("OLD_SPACE", 0x02689): "EmptyFixedInt16Array",
("OLD_SPACE", 0x026a9): "EmptyFixedUint32Array",
("OLD_SPACE", 0x026c9): "EmptyFixedInt32Array",
("OLD_SPACE", 0x026e9): "EmptyFixedFloat32Array",
("OLD_SPACE", 0x02709): "EmptyFixedFloat64Array",
("OLD_SPACE", 0x02729): "EmptyFixedUint8ClampedArray",
("OLD_SPACE", 0x02749): "EmptyScript",
("OLD_SPACE", 0x027c9): "UndefinedCell",
("OLD_SPACE", 0x027d9): "EmptySloppyArgumentsElements",
("OLD_SPACE", 0x027f9): "EmptySlowElementDictionary",
("OLD_SPACE", 0x02841): "EmptyPropertyCell",
("OLD_SPACE", 0x02869): "EmptyWeakCell",
("OLD_SPACE", 0x02879): "ArrayProtector",
("OLD_SPACE", 0x028a1): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x028b1): "SpeciesProtector",
("OLD_SPACE", 0x028d9): "StringLengthProtector",
("OLD_SPACE", 0x02901): "FastArrayIterationProtector",
("OLD_SPACE", 0x02911): "ArrayIteratorProtector",
("OLD_SPACE", 0x02939): "ArrayBufferNeuteringProtector",
("OLD_SPACE", 0x02961): "InfinityValue",
("OLD_SPACE", 0x02971): "MinusZeroValue",
("OLD_SPACE", 0x02981): "MinusInfinityValue",
}
# List of known V8 Frame Markers.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment