object-deserializer.cc 3.81 KB
Newer Older
1 2 3 4 5 6
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/snapshot/object-deserializer.h"

7
#include "src/assembler-inl.h"
8
#include "src/heap/heap-inl.h"
9 10
#include "src/isolate.h"
#include "src/objects.h"
11
#include "src/objects/allocation-site-inl.h"
12
#include "src/objects/slots.h"
13 14
#include "src/snapshot/code-serializer.h"

15
namespace v8 {
16 17
namespace internal {

18 19 20
ObjectDeserializer::ObjectDeserializer(const SerializedCodeData* data)
    : Deserializer(data, true) {}

21 22 23 24 25 26 27 28 29 30 31 32 33
MaybeHandle<SharedFunctionInfo>
ObjectDeserializer::DeserializeSharedFunctionInfo(
    Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
  ObjectDeserializer d(data);

  d.AddAttachedObject(source);

  Handle<HeapObject> result;
  return d.Deserialize(isolate).ToHandle(&result)
             ? Handle<SharedFunctionInfo>::cast(result)
             : MaybeHandle<SharedFunctionInfo>();
}

34 35
MaybeHandle<HeapObject> ObjectDeserializer::Deserialize(Isolate* isolate) {
  Initialize(isolate);
36

37
  if (!allocator()->ReserveSpace()) return MaybeHandle<HeapObject>();
38 39 40 41 42 43

  DCHECK(deserializing_user_code());
  HandleScope scope(isolate);
  Handle<HeapObject> result;
  {
    DisallowHeapAllocation no_gc;
44
    Object root;
45 46
    VisitRootPointer(Root::kPartialSnapshotCache, nullptr,
                     FullObjectSlot(&root));
47
    DeserializeDeferredObjects();
48 49 50
    FlushICache();
    LinkAllocationSites();
    LogNewMapEvents();
51
    result = handle(HeapObject::cast(root), isolate);
52
    Rehash();
53
    allocator()->RegisterDeserializedObjectsForBlackAllocation();
54 55 56 57 58
  }
  CommitPostProcessedObjects();
  return scope.CloseAndEscape(result);
}

59
void ObjectDeserializer::FlushICache() {
60
  DCHECK(deserializing_user_code());
61
  for (Code code : new_code_objects()) {
62
    // Record all references to embedded objects in the new code object.
63
    WriteBarrierForCode(code);
64 65
    FlushInstructionCache(code->raw_instruction_start(),
                          code->raw_instruction_size());
66 67 68 69
  }
}

void ObjectDeserializer::CommitPostProcessedObjects() {
70
  CHECK_LE(new_internalized_strings().size(), kMaxInt);
71
  StringTable::EnsureCapacityForDeserialization(
72
      isolate(), static_cast<int>(new_internalized_strings().size()));
73
  for (Handle<String> string : new_internalized_strings()) {
74
    DisallowHeapAllocation no_gc;
75
    StringTableInsertionKey key(*string);
76 77
    DCHECK(
        StringTable::ForwardStringIfExists(isolate(), &key, *string).is_null());
78
    StringTable::AddKeyNoResize(isolate(), &key);
79 80 81 82 83 84 85
  }

  Heap* heap = isolate()->heap();
  Factory* factory = isolate()->factory();
  for (Handle<Script> script : new_scripts()) {
    // Assign a new script id to avoid collision.
    script->set_id(isolate()->heap()->NextScriptId());
86
    LogScriptEvents(*script);
87
    // Add script to list.
88 89 90
    Handle<WeakArrayList> list = factory->script_list();
    list = WeakArrayList::AddToEnd(isolate(), list,
                                   MaybeObjectHandle::Weak(script));
91 92
    heap->SetRootScriptList(*list);
  }
93
}
94

95 96 97
void ObjectDeserializer::LinkAllocationSites() {
  DisallowHeapAllocation no_gc;
  Heap* heap = isolate()->heap();
98 99
  // Allocation sites are present in the snapshot, and must be linked into
  // a list at deserialization time.
100
  for (AllocationSite site : new_allocation_sites()) {
101 102 103 104 105 106 107 108 109 110 111
    if (!site->HasWeakNext()) continue;
    // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
    // as a (weak) root. If this root is relocated correctly, this becomes
    // unnecessary.
    if (heap->allocation_sites_list() == Smi::kZero) {
      site->set_weak_next(ReadOnlyRoots(heap).undefined_value());
    } else {
      site->set_weak_next(heap->allocation_sites_list());
    }
    heap->set_allocation_sites_list(site);
  }
112 113 114
}

}  // namespace internal
115
}  // namespace v8