v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
startup-serializer.cc
Go to the documentation of this file.
1// Copyright 2016 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
6
9#include "src/heap/heap-inl.h"
13#include "src/objects/slots.h"
16
17namespace v8 {
18namespace internal {
19
20namespace {
21
22// The isolate roots may not point at context-specific objects during
23// serialization.
24class V8_NODISCARD SanitizeIsolateScope final {
25 public:
26 SanitizeIsolateScope(Isolate* isolate, bool allow_active_isolate_for_testing,
27 const DisallowGarbageCollection& no_gc)
28 : isolate_(isolate),
30 isolate->heap()->feedback_vectors_for_profiling_tools()),
31 detached_contexts_(isolate->heap()->detached_contexts()) {
32#ifdef DEBUG
33 if (!allow_active_isolate_for_testing) {
34 // These should already be empty when creating a real snapshot.
36 ReadOnlyRoots(isolate).undefined_value());
38 ReadOnlyRoots(isolate).empty_weak_array_list());
39 }
40#endif
41
42 isolate->SetFeedbackVectorsForProfilingTools(
43 ReadOnlyRoots(isolate).undefined_value());
44 isolate->heap()->SetDetachedContexts(
45 ReadOnlyRoots(isolate).empty_weak_array_list());
46 }
47
48 ~SanitizeIsolateScope() {
49 // Restore saved fields.
50 isolate_->SetFeedbackVectorsForProfilingTools(
52 isolate_->heap()->SetDetachedContexts(detached_contexts_);
53 }
54
55 private:
56 Isolate* isolate_;
58 const Tagged<WeakArrayList> detached_contexts_;
59};
60
61} // namespace
62
64 Isolate* isolate, Snapshot::SerializerFlags flags,
65 SharedHeapSerializer* shared_heap_serializer)
66 : RootsSerializer(isolate, flags, RootIndex::kFirstStrongRoot),
67 shared_heap_serializer_(shared_heap_serializer),
68 accessor_infos_(isolate->heap()),
69 function_template_infos_(isolate->heap()) {
71
72 // This serializes any external reference which don't encode to their own
73 // index. This is so that the deserializer can verify that any entries that
74 // were deduplicated during serialization are also deduplicated in the
75 // deserializing binary.
76 ExternalReferenceTable* table = isolate->external_reference_table();
78 ++i) {
79 ExternalReferenceEncoder::Value encoded_reference =
80 EncodeExternalReference(table->address(i));
81 if (encoded_reference.index() != i) {
82 sink_.PutUint30(i, "expected reference index");
83 sink_.PutUint30(encoded_reference.index(), "actual reference index");
84 }
85 }
87 "end of deduplicated reference indices");
88}
89
99
101 SlotType slot_type) {
103#ifdef DEBUG
104 if (IsJSFunction(*obj, cage_base)) {
105 v8::base::OS::PrintError("Reference stack:\n");
106 PrintStack(std::cerr);
107 Print(*obj, std::cerr);
108 FATAL(
109 "JSFunction should be added through the context snapshot instead of "
110 "the isolate snapshot");
111 }
112#endif // DEBUG
113 {
115 Tagged<HeapObject> raw = *obj;
116 DCHECK(!IsInstructionStream(raw));
117 if (SerializeHotObject(raw)) return;
118 if (IsRootAndHasBeenSerialized(raw) && SerializeRoot(raw)) return;
119 }
120
121 if (SerializeReadOnlyObjectReference(*obj, &sink_)) return;
123 if (SerializeBackReference(*obj)) return;
124
125 if (USE_SIMULATOR_BOOL && IsAccessorInfo(*obj, cage_base)) {
126 // Wipe external reference redirects in the accessor info.
127 auto info = Cast<AccessorInfo>(obj);
128 info->remove_getter_redirection(isolate());
129 accessor_infos_.Push(*info);
130 } else if (USE_SIMULATOR_BOOL && IsFunctionTemplateInfo(*obj, cage_base)) {
131 auto info = Cast<FunctionTemplateInfo>(obj);
132 info->remove_callback_redirection(isolate());
133 function_template_infos_.Push(*info);
134 } else if (IsScript(*obj, cage_base) &&
135 Cast<Script>(obj)->IsUserJavaScript()) {
136 Cast<Script>(obj)->set_context_data(
137 ReadOnlyRoots(isolate()).uninitialized_symbol());
138 } else if (IsSharedFunctionInfo(*obj, cage_base)) {
139 // Clear inferred name for native functions.
140 auto shared = Cast<SharedFunctionInfo>(obj);
141 if (!shared->IsSubjectToDebugging() && shared->HasUncompiledData()) {
142 shared->uncompiled_data(isolate())->set_inferred_name(
143 ReadOnlyRoots(isolate()).empty_string());
144 }
145 }
146
147 CheckRehashability(*obj);
148
149 // Object has not yet been serialized. Serialize it here.
151 ObjectSerializer object_serializer(this, obj, &sink_);
152 object_serializer.Serialize(slot_type);
153}
154
156 // This comes right after serialization of the context snapshot, where we
157 // add entries to the startup object cache of the startup snapshot. Add
158 // one entry with 'undefined' to terminate the startup object cache.
159 Tagged<Object> undefined = ReadOnlyRoots(isolate()).undefined_value();
160 VisitRootPointer(Root::kStartupObjectCache, nullptr,
161 FullObjectSlot(&undefined));
162
166 Pad();
167}
168
170 const DisallowGarbageCollection& no_gc) {
171 Isolate* isolate = this->isolate();
172 // No active threads.
174
175 SanitizeIsolateScope sanitize_isolate(
176 isolate, allow_active_isolate_for_testing(), no_gc);
177
178 // Visit smi roots and immortal immovables first to make sure they end up in
179 // the first page.
180 isolate->heap()->IterateSmiRoots(this);
181 isolate->heap()->IterateRoots(
184}
185
187 Isolate* isolate, std::vector<Tagged<Context>>* contexts)
188 : isolate_(isolate) {
189 AddToSet(Cast<FixedArray>(isolate->heap()->serialized_objects()));
190 for (auto const& context : *contexts) {
191 AddToSet(Cast<FixedArray>(context->serialized_objects()));
192 }
193}
194
200
203 int cache_index = SerializeInObjectCache(obj);
204 sink->Put(kStartupObjectCache, "StartupObjectCache");
205 sink->PutUint30(cache_index, "startup_object_cache_index");
206}
207
209 Isolate* isolate = this->isolate();
210 CHECK(IsUndefined(isolate->heap()->dirty_js_finalization_registries_list(),
211 isolate));
212 CHECK(IsUndefined(
213 isolate->heap()->dirty_js_finalization_registries_list_tail(), isolate));
214}
215
217 int length = serialized->length();
218 for (int i = 0; i < length; i++) serialized_.insert(serialized->get(i));
219}
220
222 const char* description,
225 for (FullObjectSlot p = start; p < end; ++p) {
226 if (serialized_.find(*p) != serialized_.end()) continue;
227 PrintF("%s handle not serialized: ",
228 root == Root::kGlobalHandles ? "global" : "eternal");
229 Print(*p);
230 PrintF("\n");
231 ok_ = false;
232 }
233}
234
241
242} // namespace internal
243} // namespace v8
Isolate * isolate_
void IterateAllRoots(RootVisitor *visitor)
void IterateAllRoots(RootVisitor *v)
void IterateWeakRoots(RootVisitor *v, base::EnumSet< SkipRoot > options)
Definition heap.cc:4532
GlobalHandles * global_handles() const
Definition isolate.h:1416
EternalHandles * eternal_handles() const
Definition isolate.h:1420
TracedHandles * traced_handles()
Definition isolate.h:1418
ThreadManager * thread_manager() const
Definition isolate.h:1422
static V8_EXPORT_PRIVATE bool Contains(Address address)
virtual void VisitRootPointer(Root root, const char *description, FullObjectSlot p)
Definition visitors.h:75
void CheckRehashability(Tagged< HeapObject > obj)
int SerializeInObjectCache(Handle< HeapObject > object)
bool IsRootAndHasBeenSerialized(Tagged< HeapObject > obj) const
std::unordered_set< Tagged< Object >, Object::Hasher > serialized_
SerializedHandleChecker(Isolate *isolate, std::vector< Tagged< Context > > *contexts)
void VisitRootPointers(Root root, const char *description, FullObjectSlot start, FullObjectSlot end) override
void AddToSet(Tagged< FixedArray > serialized)
void RestoreExternalReferenceRedirector(Isolate *isolate, Tagged< AccessorInfo > accessor_info)
PtrComprCageBase cage_base() const
Definition serializer.h:199
ExternalReferenceEncoder::Value EncodeExternalReference(Address addr)
Isolate * isolate() const
Definition serializer.h:195
SnapshotByteSink sink_
Definition serializer.h:323
bool SerializeRoot(Tagged< HeapObject > obj)
bool SerializeReadOnlyObjectReference(Tagged< HeapObject > obj, SnapshotByteSink *sink)
void OutputStatistics(const char *name)
void Pad(int padding_offset=0)
bool allow_active_isolate_for_testing() const
Definition serializer.h:328
bool SerializeHotObject(Tagged< HeapObject > obj)
bool SerializeBackReference(Tagged< HeapObject > obj)
bool SerializeUsingSharedHeapObjectCache(SnapshotByteSink *sink, Handle< HeapObject > obj)
void PutUint30(uint32_t integer, const char *description)
void Put(uint8_t b, const char *description)
SharedHeapSerializer *const shared_heap_serializer_
GlobalHandleVector< FunctionTemplateInfo > function_template_infos_
StartupSerializer(Isolate *isolate, Snapshot::SerializerFlags flags, SharedHeapSerializer *shared_heap_serializer)
void SerializeUsingStartupObjectCache(SnapshotByteSink *sink, Handle< HeapObject > obj)
void SerializeObjectImpl(Handle< HeapObject > o, SlotType slot_type) override
bool SerializeUsingSharedHeapObjectCache(SnapshotByteSink *sink, Handle< HeapObject > obj)
void SerializeStrongReferences(const DisallowGarbageCollection &no_gc)
GlobalHandleVector< AccessorInfo > accessor_infos_
ThreadState * FirstThreadStateInUse()
Definition v8threads.cc:208
void Iterate(RootVisitor *)
#define USE_SIMULATOR_BOOL
Definition globals.h:73
int start
int end
void PrintF(const char *format,...)
Definition utils.cc:39
void Print(Tagged< Object > obj)
Definition objects.h:774
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define FATAL(...)
Definition logging.h:47
#define CHECK(condition)
Definition logging.h:124
#define CHECK_NULL(val)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
const Tagged< Object > feedback_vectors_for_profiling_tools_
const Tagged< WeakArrayList > detached_contexts_
#define V8_NODISCARD
Definition v8config.h:693