1 // Copyright 2017 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/startup-deserializer.h"
6
7 #include "src/api.h"
8 #include "src/assembler-inl.h"
9 #include "src/code-stubs.h"
10 #include "src/code-tracer.h"
11 #include "src/heap/heap-inl.h"
12 #include "src/snapshot/builtin-deserializer.h"
13 #include "src/snapshot/snapshot.h"
14
15 namespace v8 {
16 namespace internal {
17
DeserializeInto(Isolate * isolate)18 void StartupDeserializer::DeserializeInto(Isolate* isolate) {
19 Initialize(isolate);
20
21 BuiltinDeserializer builtin_deserializer(isolate, builtin_data_);
22
23 if (!DefaultDeserializerAllocator::ReserveSpace(this,
24 &builtin_deserializer)) {
25 V8::FatalProcessOutOfMemory(isolate, "StartupDeserializer");
26 }
27
28 // No active threads.
29 DCHECK_NULL(isolate->thread_manager()->FirstThreadStateInUse());
30 // No active handles.
31 DCHECK(isolate->handle_scope_implementer()->blocks()->empty());
32 // Partial snapshot cache is not yet populated.
33 DCHECK(isolate->partial_snapshot_cache()->empty());
34 // Builtins are not yet created.
35 DCHECK(!isolate->builtins()->is_initialized());
36
37 {
38 DisallowHeapAllocation no_gc;
39 isolate->heap()->IterateSmiRoots(this);
40 isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
41 isolate->heap()->RepairFreeListsAfterDeserialization();
42 isolate->heap()->IterateWeakRoots(this, VISIT_FOR_SERIALIZATION);
43 DeserializeDeferredObjects();
44 RestoreExternalReferenceRedirectors(accessor_infos());
45 RestoreExternalReferenceRedirectors(call_handler_infos());
46
47 // Deserialize eager builtins from the builtin snapshot. Note that deferred
48 // objects must have been deserialized prior to this.
49 builtin_deserializer.DeserializeEagerBuiltinsAndHandlers();
50
51 // Flush the instruction cache for the entire code-space. Must happen after
52 // builtins deserialization.
53 FlushICacheForNewIsolate();
54 }
55
56 isolate->heap()->set_native_contexts_list(
57 ReadOnlyRoots(isolate).undefined_value());
58 // The allocation site list is build during root iteration, but if no sites
59 // were encountered then it needs to be initialized to undefined.
60 if (isolate->heap()->allocation_sites_list() == Smi::kZero) {
61 isolate->heap()->set_allocation_sites_list(
62 ReadOnlyRoots(isolate).undefined_value());
63 }
64
65 // Issue code events for newly deserialized code objects.
66 LOG_CODE_EVENT(isolate, LogCodeObjects());
67 LOG_CODE_EVENT(isolate, LogBytecodeHandlers());
68 LOG_CODE_EVENT(isolate, LogCompiledFunctions());
69
70 isolate->builtins()->MarkInitialized();
71
72 // If needed, print the dissassembly of deserialized code objects.
73 // Needs to be called after the builtins are marked as initialized, in order
74 // to display the builtin names.
75 PrintDisassembledCodeObjects();
76
77 if (FLAG_rehash_snapshot && can_rehash()) RehashHeap();
78 }
79
FlushICacheForNewIsolate()80 void StartupDeserializer::FlushICacheForNewIsolate() {
81 DCHECK(!deserializing_user_code());
82 // The entire isolate is newly deserialized. Simply flush all code pages.
83 for (Page* p : *isolate()->heap()->code_space()) {
84 Assembler::FlushICache(p->area_start(), p->area_end() - p->area_start());
85 }
86 }
87
PrintDisassembledCodeObjects()88 void StartupDeserializer::PrintDisassembledCodeObjects() {
89 #ifdef ENABLE_DISASSEMBLER
90 if (FLAG_print_builtin_code) {
91 Heap* heap = isolate()->heap();
92 HeapIterator iterator(heap);
93 DisallowHeapAllocation no_gc;
94
95 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
96 OFStream os(tracing_scope.file());
97
98 for (HeapObject* obj = iterator.next(); obj != nullptr;
99 obj = iterator.next()) {
100 if (obj->IsCode()) {
101 Code* code = Code::cast(obj);
102 // Printing of builtins and bytecode handlers is handled during their
103 // deserialization.
104 if (code->kind() != Code::BUILTIN &&
105 code->kind() != Code::BYTECODE_HANDLER) {
106 code->PrintBuiltinCode(isolate(), nullptr);
107 }
108 }
109 }
110 }
111 #endif
112 }
113
RehashHeap()114 void StartupDeserializer::RehashHeap() {
115 DCHECK(FLAG_rehash_snapshot && can_rehash());
116 isolate()->heap()->InitializeHashSeed();
117 Rehash();
118 }
119
120 } // namespace internal
121 } // namespace v8
122