• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,Snapshot::SerializerFlags flags)19 ReadOnlySerializer::ReadOnlySerializer(Isolate* isolate,
20                                        Snapshot::SerializerFlags flags)
21     : RootsSerializer(isolate, flags, RootIndex::kFirstReadOnlyRoot)
22 #ifdef DEBUG
23       ,
24       serialized_objects_(isolate->heap()),
25       did_serialize_not_mapped_symbol_(false)
26 #endif
27 {
28   STATIC_ASSERT(RootIndex::kFirstReadOnlyRoot == RootIndex::kFirstRoot);
29 }
30 
~ReadOnlySerializer()31 ReadOnlySerializer::~ReadOnlySerializer() {
32   OutputStatistics("ReadOnlySerializer");
33 }
34 
SerializeObjectImpl(Handle<HeapObject> obj)35 void ReadOnlySerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
36   CHECK(ReadOnlyHeap::Contains(*obj));
37   CHECK_IMPLIES(obj->IsString(), obj->IsInternalizedString());
38 
39   // There should be no references to the not_mapped_symbol except for the entry
40   // in the root table, so don't try to serialize a reference and rely on the
41   // below CHECK(!did_serialize_not_mapped_symbol_) to make sure it doesn't
42   // serialize twice.
43   if (*obj != ReadOnlyRoots(isolate()).not_mapped_symbol()) {
44     if (SerializeHotObject(obj)) return;
45     if (IsRootAndHasBeenSerialized(*obj) && SerializeRoot(obj)) {
46       return;
47     }
48     if (SerializeBackReference(obj)) return;
49   }
50 
51   CheckRehashability(*obj);
52 
53   // Object has not yet been serialized.  Serialize it here.
54   ObjectSerializer object_serializer(this, obj, &sink_);
55   object_serializer.Serialize();
56 #ifdef DEBUG
57   if (*obj == ReadOnlyRoots(isolate()).not_mapped_symbol()) {
58     CHECK(!did_serialize_not_mapped_symbol_);
59     did_serialize_not_mapped_symbol_ = true;
60   } else {
61     CHECK_NULL(serialized_objects_.Find(obj));
62     // There's no "IdentitySet", so use an IdentityMap with a value that is
63     // later ignored.
64     serialized_objects_.Insert(obj, 0);
65   }
66 #endif
67 }
68 
SerializeReadOnlyRoots()69 void ReadOnlySerializer::SerializeReadOnlyRoots() {
70   // No active threads.
71   CHECK_NULL(isolate()->thread_manager()->FirstThreadStateInUse());
72   // No active or weak handles.
73   CHECK_IMPLIES(!allow_active_isolate_for_testing(),
74                 isolate()->handle_scope_implementer()->blocks()->empty());
75 
76   ReadOnlyRoots(isolate()).Iterate(this);
77 }
78 
FinalizeSerialization()79 void ReadOnlySerializer::FinalizeSerialization() {
80   // This comes right after serialization of the other snapshots, where we
81   // add entries to the read-only object cache. Add one entry with 'undefined'
82   // to terminate the read-only object cache.
83   Object undefined = ReadOnlyRoots(isolate()).undefined_value();
84   VisitRootPointer(Root::kReadOnlyObjectCache, nullptr,
85                    FullObjectSlot(&undefined));
86   SerializeDeferredObjects();
87   Pad();
88 
89 #ifdef DEBUG
90   // Check that every object on read-only heap is reachable (and was
91   // serialized).
92   ReadOnlyHeapObjectIterator iterator(isolate()->read_only_heap());
93   for (HeapObject object = iterator.Next(); !object.is_null();
94        object = iterator.Next()) {
95     if (object == ReadOnlyRoots(isolate()).not_mapped_symbol()) {
96       CHECK(did_serialize_not_mapped_symbol_);
97     } else {
98       CHECK_NOT_NULL(serialized_objects_.Find(object));
99     }
100   }
101 #endif
102 }
103 
MustBeDeferred(HeapObject object)104 bool ReadOnlySerializer::MustBeDeferred(HeapObject object) {
105   if (root_has_been_serialized(RootIndex::kFreeSpaceMap) &&
106       root_has_been_serialized(RootIndex::kOnePointerFillerMap) &&
107       root_has_been_serialized(RootIndex::kTwoPointerFillerMap)) {
108     // All required root objects are serialized, so any aligned objects can
109     // be saved without problems.
110     return false;
111   }
112   // Defer objects with special alignment requirements until the filler roots
113   // are serialized.
114   return HeapObject::RequiredAlignment(object.map()) != kWordAligned;
115 }
116 
SerializeUsingReadOnlyObjectCache(SnapshotByteSink * sink,Handle<HeapObject> obj)117 bool ReadOnlySerializer::SerializeUsingReadOnlyObjectCache(
118     SnapshotByteSink* sink, Handle<HeapObject> obj) {
119   if (!ReadOnlyHeap::Contains(*obj)) return false;
120 
121   // Get the cache index and serialize it into the read-only snapshot if
122   // necessary.
123   int cache_index = SerializeInObjectCache(obj);
124 
125   // Writing out the cache entry into the calling serializer's sink.
126   sink->Put(kReadOnlyObjectCache, "ReadOnlyObjectCache");
127   sink->PutInt(cache_index, "read_only_object_cache_index");
128 
129   return true;
130 }
131 
132 }  // namespace internal
133 }  // namespace v8
134