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
16namespace v8 {
17namespace internal {
18
19ReadOnlySerializer::ReadOnlySerializer(Isolate* isolate)
20 : RootsSerializer(isolate, RootIndex::kFirstReadOnlyRoot) {
21 STATIC_ASSERT(RootIndex::kFirstReadOnlyRoot == RootIndex::kFirstRoot);
22}
23
24ReadOnlySerializer::~ReadOnlySerializer() {
25 OutputStatistics("ReadOnlySerializer");
26}
27
28void 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
45void 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
54void 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
65bool 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
81bool 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