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