Home | History | Annotate | Download | only in snapshot
      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