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 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 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 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 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