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