5 #include "src/snapshot/startup-serializer.h" 8 #include "src/code-tracer.h" 9 #include "src/contexts.h" 10 #include "src/global-handles.h" 11 #include "src/objects-inl.h" 12 #include "src/objects/slots.h" 13 #include "src/snapshot/read-only-serializer.h" 14 #include "src/v8threads.h" 19 StartupSerializer::StartupSerializer(Isolate* isolate,
20 ReadOnlySerializer* read_only_serializer)
21 : RootsSerializer(isolate, RootIndex::kFirstStrongRoot),
22 read_only_serializer_(read_only_serializer) {
23 InitializeCodeAddressMap();
26 StartupSerializer::~StartupSerializer() {
27 RestoreExternalReferenceRedirectors(accessor_infos_);
28 RestoreExternalReferenceRedirectors(call_handler_infos_);
29 OutputStatistics(
"StartupSerializer");
39 HeapObject* MaybeCanonicalizeBuiltin(Isolate* isolate, HeapObject* obj) {
40 if (!obj->IsCode())
return obj;
42 const int builtin_index = Code::cast(obj)->builtin_index();
43 if (!Builtins::IsBuiltinId(builtin_index))
return obj;
45 return isolate->builtins()->builtin(builtin_index);
50 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
51 WhereToPoint where_to_point,
int skip) {
52 DCHECK(!obj->IsJSFunction());
56 obj = MaybeCanonicalizeBuiltin(isolate(), obj);
58 if (SerializeHotObject(obj, how_to_code, where_to_point, skip))
return;
59 if (IsRootAndHasBeenSerialized(obj) &&
60 SerializeRoot(obj, how_to_code, where_to_point, skip))
62 if (SerializeUsingReadOnlyObjectCache(&sink_, obj, how_to_code,
63 where_to_point, skip))
65 if (SerializeBackReference(obj, how_to_code, where_to_point, skip))
return;
68 bool use_simulator =
false;
73 if (use_simulator && obj->IsAccessorInfo()) {
75 AccessorInfo* info = AccessorInfo::cast(obj);
76 Address original_address = Foreign::cast(info->getter())->foreign_address();
77 Foreign::cast(info->js_getter())->set_foreign_address(original_address);
78 accessor_infos_.push_back(info);
79 }
else if (use_simulator && obj->IsCallHandlerInfo()) {
80 CallHandlerInfo* info = CallHandlerInfo::cast(obj);
81 Address original_address =
82 Foreign::cast(info->callback())->foreign_address();
83 Foreign::cast(info->js_callback())->set_foreign_address(original_address);
84 call_handler_infos_.push_back(info);
85 }
else if (obj->IsScript() && Script::cast(obj)->IsUserJavaScript()) {
86 Script::cast(obj)->set_context_data(
87 ReadOnlyRoots(isolate()).uninitialized_symbol());
88 }
else if (obj->IsSharedFunctionInfo()) {
90 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
91 if (!shared->IsSubjectToDebugging() && shared->HasUncompiledData()) {
92 shared->uncompiled_data()->set_inferred_name(
93 ReadOnlyRoots(isolate()).empty_string());
97 CheckRehashability(obj);
100 DCHECK(!isolate()->heap()->read_only_space()->Contains(obj));
101 ObjectSerializer object_serializer(
this, obj, &sink_, how_to_code,
103 object_serializer.Serialize();
106 void StartupSerializer::SerializeWeakReferencesAndDeferred() {
110 Object* undefined = ReadOnlyRoots(isolate()).undefined_value();
111 VisitRootPointer(Root::kPartialSnapshotCache,
nullptr,
112 ObjectSlot(&undefined));
113 isolate()->heap()->IterateWeakRoots(
this, VISIT_FOR_SERIALIZATION);
114 SerializeDeferredObjects();
118 void StartupSerializer::SerializeStrongReferences() {
119 Isolate* isolate = this->isolate();
121 CHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse());
123 CHECK(isolate->handle_scope_implementer()->blocks()->empty());
128 isolate->heap()->ClearStackLimits();
129 isolate->heap()->IterateSmiRoots(
this);
130 isolate->heap()->SetStackLimits();
132 isolate->heap()->IterateStrongRoots(
this, VISIT_FOR_SERIALIZATION);
135 SerializedHandleChecker::SerializedHandleChecker(Isolate* isolate,
136 std::vector<Context>* contexts)
137 : isolate_(isolate) {
138 AddToSet(isolate->heap()->serialized_objects());
139 for (
auto const& context : *contexts) {
140 AddToSet(context->serialized_objects());
144 bool StartupSerializer::SerializeUsingReadOnlyObjectCache(
145 SnapshotByteSink* sink, HeapObject* obj, HowToCode how_to_code,
146 WhereToPoint where_to_point,
int skip) {
147 return read_only_serializer_->SerializeUsingReadOnlyObjectCache(
148 sink, obj, how_to_code, where_to_point, skip);
151 void StartupSerializer::SerializeUsingPartialSnapshotCache(
152 SnapshotByteSink* sink, HeapObject* obj, HowToCode how_to_code,
153 WhereToPoint where_to_point,
int skip) {
154 FlushSkip(sink, skip);
156 int cache_index = SerializeInObjectCache(obj);
157 sink->Put(kPartialSnapshotCache + how_to_code + where_to_point,
158 "PartialSnapshotCache");
159 sink->PutInt(cache_index,
"partial_snapshot_cache_index");
162 void SerializedHandleChecker::AddToSet(FixedArray serialized) {
163 int length = serialized->length();
164 for (
int i = 0;
i < length;
i++) serialized_.insert(serialized->get(
i));
167 void SerializedHandleChecker::VisitRootPointers(Root root,
168 const char* description,
171 for (ObjectSlot p = start; p < end; ++p) {
172 if (serialized_.find(*p) != serialized_.end())
continue;
173 PrintF(
"%s handle not serialized: ",
174 root == Root::kGlobalHandles ?
"global" :
"eternal");
180 bool SerializedHandleChecker::CheckGlobalAndEternalHandles() {
181 isolate_->global_handles()->IterateAllRoots(
this);
182 isolate_->eternal_handles()->IterateAllRoots(
this);