1 // Copyright 2018 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/snapshot/read-only-serializer.h"
6
7 #include "src/api/api.h"
8 #include "src/diagnostics/code-tracer.h"
9 #include "src/execution/v8threads.h"
10 #include "src/handles/global-handles.h"
11 #include "src/heap/read-only-heap.h"
12 #include "src/objects/objects-inl.h"
13 #include "src/objects/slots.h"
14 #include "src/snapshot/startup-serializer.h"
15
16 namespace v8 {
17 namespace internal {
18
ReadOnlySerializer(Isolate * isolate)19 ReadOnlySerializer::ReadOnlySerializer(Isolate* isolate)
20 : RootsSerializer(isolate, RootIndex::kFirstReadOnlyRoot) {
21 STATIC_ASSERT(RootIndex::kFirstReadOnlyRoot == RootIndex::kFirstRoot);
22 allocator()->UseCustomChunkSize(FLAG_serialization_chunk_size);
23 }
24
~ReadOnlySerializer()25 ReadOnlySerializer::~ReadOnlySerializer() {
26 OutputStatistics("ReadOnlySerializer");
27 }
28
SerializeObject(HeapObject obj)29 void ReadOnlySerializer::SerializeObject(HeapObject obj) {
30 CHECK(ReadOnlyHeap::Contains(obj));
31 CHECK_IMPLIES(obj.IsString(), obj.IsInternalizedString());
32
33 if (SerializeHotObject(obj)) return;
34 if (IsRootAndHasBeenSerialized(obj) && SerializeRoot(obj)) {
35 return;
36 }
37 if (SerializeBackReference(obj)) return;
38
39 CheckRehashability(obj);
40
41 // Object has not yet been serialized. Serialize it here.
42 ObjectSerializer object_serializer(this, obj, &sink_);
43 object_serializer.Serialize();
44 #ifdef DEBUG
45 serialized_objects_.insert(obj);
46 #endif
47 }
48
SerializeReadOnlyRoots()49 void ReadOnlySerializer::SerializeReadOnlyRoots() {
50 // No active threads.
51 CHECK_NULL(isolate()->thread_manager()->FirstThreadStateInUse());
52 // No active or weak handles.
53 CHECK(isolate()->handle_scope_implementer()->blocks()->empty());
54
55 ReadOnlyRoots(isolate()).Iterate(this);
56 }
57
FinalizeSerialization()58 void ReadOnlySerializer::FinalizeSerialization() {
59 // This comes right after serialization of the other snapshots, where we
60 // add entries to the read-only object cache. Add one entry with 'undefined'
61 // to terminate the read-only object cache.
62 Object undefined = ReadOnlyRoots(isolate()).undefined_value();
63 VisitRootPointer(Root::kReadOnlyObjectCache, nullptr,
64 FullObjectSlot(&undefined));
65 SerializeDeferredObjects();
66 Pad();
67
68 #ifdef DEBUG
69 // Check that every object on read-only heap is reachable (and was
70 // serialized).
71 ReadOnlyHeapObjectIterator iterator(isolate()->read_only_heap());
72 for (HeapObject object = iterator.Next(); !object.is_null();
73 object = iterator.Next()) {
74 CHECK(serialized_objects_.count(object));
75 }
76 #endif
77 }
78
MustBeDeferred(HeapObject object)79 bool ReadOnlySerializer::MustBeDeferred(HeapObject object) {
80 if (root_has_been_serialized(RootIndex::kFreeSpaceMap) &&
81 root_has_been_serialized(RootIndex::kOnePointerFillerMap) &&
82 root_has_been_serialized(RootIndex::kTwoPointerFillerMap)) {
83 // All required root objects are serialized, so any aligned objects can
84 // be saved without problems.
85 return false;
86 }
87 // Just defer everything except for Map objects until all required roots are
88 // serialized. Some objects may have special alignment requirements, that may
89 // not be fulfilled during deserialization until few first root objects are
90 // serialized. But we must serialize Map objects since deserializer checks
91 // that these root objects are indeed Maps.
92 return !object.IsMap();
93 }
94
SerializeUsingReadOnlyObjectCache(SnapshotByteSink * sink,HeapObject obj)95 bool ReadOnlySerializer::SerializeUsingReadOnlyObjectCache(
96 SnapshotByteSink* sink, HeapObject obj) {
97 if (!ReadOnlyHeap::Contains(obj)) return false;
98
99 // Get the cache index and serialize it into the read-only snapshot if
100 // necessary.
101 int cache_index = SerializeInObjectCache(obj);
102
103 // Writing out the cache entry into the calling serializer's sink.
104 sink->Put(kReadOnlyObjectCache, "ReadOnlyObjectCache");
105 sink->PutInt(cache_index, "read_only_object_cache_index");
106
107 return true;
108 }
109
110 } // namespace internal
111 } // namespace v8
112