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/api.h"
8#include "src/codegen/assembler-inl.h"
9#include "src/execution/v8threads.h"
10#include "src/heap/heap-inl.h"
11#include "src/logging/log.h"
12#include "src/snapshot/snapshot.h"
13
14namespace v8 {
15namespace internal {
16
17void StartupDeserializer::DeserializeIntoIsolate() {
18  HandleScope scope(isolate());
19
20  // No active threads.
21  DCHECK_NULL(isolate()->thread_manager()->FirstThreadStateInUse());
22  // No active handles.
23  DCHECK(isolate()->handle_scope_implementer()->blocks()->empty());
24  // Startup object cache is not yet populated.
25  DCHECK(isolate()->startup_object_cache()->empty());
26  // Builtins are not yet created.
27  DCHECK(!isolate()->builtins()->is_initialized());
28
29  {
30    isolate()->heap()->IterateSmiRoots(this);
31    isolate()->heap()->IterateRoots(
32        this,
33        base::EnumSet<SkipRoot>{SkipRoot::kUnserializable, SkipRoot::kWeak});
34    IterateStartupObjectCache(isolate(), this);
35
36    isolate()->heap()->IterateWeakRoots(
37        this, base::EnumSet<SkipRoot>{SkipRoot::kUnserializable});
38    DeserializeDeferredObjects();
39    for (Handle<AccessorInfo> info : accessor_infos()) {
40      RestoreExternalReferenceRedirector(isolate(), *info);
41    }
42    for (Handle<CallHandlerInfo> info : call_handler_infos()) {
43      RestoreExternalReferenceRedirector(isolate(), *info);
44    }
45
46    // Flush the instruction cache for the entire code-space. Must happen after
47    // builtins deserialization.
48    FlushICache();
49  }
50
51  CheckNoArrayBufferBackingStores();
52
53  isolate()->heap()->set_native_contexts_list(
54      ReadOnlyRoots(isolate()).undefined_value());
55  // The allocation site list is build during root iteration, but if no sites
56  // were encountered then it needs to be initialized to undefined.
57  if (isolate()->heap()->allocation_sites_list() == Smi::zero()) {
58    isolate()->heap()->set_allocation_sites_list(
59        ReadOnlyRoots(isolate()).undefined_value());
60  }
61  isolate()->heap()->set_dirty_js_finalization_registries_list(
62      ReadOnlyRoots(isolate()).undefined_value());
63  isolate()->heap()->set_dirty_js_finalization_registries_list_tail(
64      ReadOnlyRoots(isolate()).undefined_value());
65
66  isolate()->builtins()->MarkInitialized();
67
68  LogNewMapEvents();
69  WeakenDescriptorArrays();
70
71  if (should_rehash()) {
72    // Hash seed was initialized in ReadOnlyDeserializer.
73    Rehash();
74  }
75}
76
77void StartupDeserializer::LogNewMapEvents() {
78  if (FLAG_log_maps) LOG(isolate(), LogAllMaps());
79}
80
81void StartupDeserializer::FlushICache() {
82  DCHECK(!deserializing_user_code());
83  // The entire isolate is newly deserialized. Simply flush all code pages.
84  for (Page* p : *isolate()->heap()->code_space()) {
85    FlushInstructionCache(p->area_start(), p->area_end() - p->area_start());
86  }
87}
88
89}  // namespace internal
90}  // namespace v8
91