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