11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/snapshot/object-deserializer.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/codegen/assembler-inl.h"
81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
91cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
101cb0ef41Sopenharmony_ci#include "src/heap/local-factory-inl.h"
111cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h"
121cb0ef41Sopenharmony_ci#include "src/objects/js-array-buffer-inl.h"
131cb0ef41Sopenharmony_ci#include "src/objects/objects.h"
141cb0ef41Sopenharmony_ci#include "src/objects/slots.h"
151cb0ef41Sopenharmony_ci#include "src/snapshot/code-serializer.h"
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace v8 {
181cb0ef41Sopenharmony_cinamespace internal {
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciObjectDeserializer::ObjectDeserializer(Isolate* isolate,
211cb0ef41Sopenharmony_ci                                       const SerializedCodeData* data)
221cb0ef41Sopenharmony_ci    : Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
231cb0ef41Sopenharmony_ci                   false) {}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo>
261cb0ef41Sopenharmony_ciObjectDeserializer::DeserializeSharedFunctionInfo(
271cb0ef41Sopenharmony_ci    Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
281cb0ef41Sopenharmony_ci  ObjectDeserializer d(isolate, data);
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  d.AddAttachedObject(source);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  Handle<HeapObject> result;
331cb0ef41Sopenharmony_ci  return d.Deserialize().ToHandle(&result)
341cb0ef41Sopenharmony_ci             ? Handle<SharedFunctionInfo>::cast(result)
351cb0ef41Sopenharmony_ci             : MaybeHandle<SharedFunctionInfo>();
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciMaybeHandle<HeapObject> ObjectDeserializer::Deserialize() {
391cb0ef41Sopenharmony_ci  DCHECK(deserializing_user_code());
401cb0ef41Sopenharmony_ci  HandleScope scope(isolate());
411cb0ef41Sopenharmony_ci  Handle<HeapObject> result;
421cb0ef41Sopenharmony_ci  {
431cb0ef41Sopenharmony_ci    result = ReadObject();
441cb0ef41Sopenharmony_ci    DeserializeDeferredObjects();
451cb0ef41Sopenharmony_ci    CHECK(new_code_objects().empty());
461cb0ef41Sopenharmony_ci    LinkAllocationSites();
471cb0ef41Sopenharmony_ci    CHECK(new_maps().empty());
481cb0ef41Sopenharmony_ci    WeakenDescriptorArrays();
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  Rehash();
521cb0ef41Sopenharmony_ci  CommitPostProcessedObjects();
531cb0ef41Sopenharmony_ci  return scope.CloseAndEscape(result);
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_civoid ObjectDeserializer::CommitPostProcessedObjects() {
571cb0ef41Sopenharmony_ci  for (Handle<JSArrayBuffer> buffer : new_off_heap_array_buffers()) {
581cb0ef41Sopenharmony_ci    uint32_t store_index = buffer->GetBackingStoreRefForDeserialization();
591cb0ef41Sopenharmony_ci    auto bs = backing_store(store_index);
601cb0ef41Sopenharmony_ci    SharedFlag shared =
611cb0ef41Sopenharmony_ci        bs && bs->is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared;
621cb0ef41Sopenharmony_ci    // TODO(v8:11111): Support RAB / GSAB.
631cb0ef41Sopenharmony_ci    CHECK(!bs || !bs->is_resizable());
641cb0ef41Sopenharmony_ci    buffer->Setup(shared, ResizableFlag::kNotResizable, bs);
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  for (Handle<Script> script : new_scripts()) {
681cb0ef41Sopenharmony_ci    // Assign a new script id to avoid collision.
691cb0ef41Sopenharmony_ci    script->set_id(isolate()->GetNextScriptId());
701cb0ef41Sopenharmony_ci    LogScriptEvents(*script);
711cb0ef41Sopenharmony_ci    // Add script to list.
721cb0ef41Sopenharmony_ci    Handle<WeakArrayList> list = isolate()->factory()->script_list();
731cb0ef41Sopenharmony_ci    list = WeakArrayList::AddToEnd(isolate(), list,
741cb0ef41Sopenharmony_ci                                   MaybeObjectHandle::Weak(script));
751cb0ef41Sopenharmony_ci    isolate()->heap()->SetRootScriptList(*list);
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_civoid ObjectDeserializer::LinkAllocationSites() {
801cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
811cb0ef41Sopenharmony_ci  Heap* heap = isolate()->heap();
821cb0ef41Sopenharmony_ci  // Allocation sites are present in the snapshot, and must be linked into
831cb0ef41Sopenharmony_ci  // a list at deserialization time.
841cb0ef41Sopenharmony_ci  for (Handle<AllocationSite> site : new_allocation_sites()) {
851cb0ef41Sopenharmony_ci    if (!site->HasWeakNext()) continue;
861cb0ef41Sopenharmony_ci    // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
871cb0ef41Sopenharmony_ci    // as a (weak) root. If this root is relocated correctly, this becomes
881cb0ef41Sopenharmony_ci    // unnecessary.
891cb0ef41Sopenharmony_ci    if (heap->allocation_sites_list() == Smi::zero()) {
901cb0ef41Sopenharmony_ci      site->set_weak_next(ReadOnlyRoots(heap).undefined_value());
911cb0ef41Sopenharmony_ci    } else {
921cb0ef41Sopenharmony_ci      site->set_weak_next(heap->allocation_sites_list());
931cb0ef41Sopenharmony_ci    }
941cb0ef41Sopenharmony_ci    heap->set_allocation_sites_list(*site);
951cb0ef41Sopenharmony_ci  }
961cb0ef41Sopenharmony_ci}
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ciOffThreadObjectDeserializer::OffThreadObjectDeserializer(
991cb0ef41Sopenharmony_ci    LocalIsolate* isolate, const SerializedCodeData* data)
1001cb0ef41Sopenharmony_ci    : Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
1011cb0ef41Sopenharmony_ci                   false) {}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ciMaybeHandle<SharedFunctionInfo>
1041cb0ef41Sopenharmony_ciOffThreadObjectDeserializer::DeserializeSharedFunctionInfo(
1051cb0ef41Sopenharmony_ci    LocalIsolate* isolate, const SerializedCodeData* data,
1061cb0ef41Sopenharmony_ci    std::vector<Handle<Script>>* deserialized_scripts) {
1071cb0ef41Sopenharmony_ci  OffThreadObjectDeserializer d(isolate, data);
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  // Attach the empty string as the source.
1101cb0ef41Sopenharmony_ci  d.AddAttachedObject(isolate->factory()->empty_string());
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  Handle<HeapObject> result;
1131cb0ef41Sopenharmony_ci  if (!d.Deserialize(deserialized_scripts).ToHandle(&result)) {
1141cb0ef41Sopenharmony_ci    return MaybeHandle<SharedFunctionInfo>();
1151cb0ef41Sopenharmony_ci  }
1161cb0ef41Sopenharmony_ci  return Handle<SharedFunctionInfo>::cast(result);
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ciMaybeHandle<HeapObject> OffThreadObjectDeserializer::Deserialize(
1201cb0ef41Sopenharmony_ci    std::vector<Handle<Script>>* deserialized_scripts) {
1211cb0ef41Sopenharmony_ci  DCHECK(deserializing_user_code());
1221cb0ef41Sopenharmony_ci  LocalHandleScope scope(isolate());
1231cb0ef41Sopenharmony_ci  Handle<HeapObject> result;
1241cb0ef41Sopenharmony_ci  {
1251cb0ef41Sopenharmony_ci    result = ReadObject();
1261cb0ef41Sopenharmony_ci    DeserializeDeferredObjects();
1271cb0ef41Sopenharmony_ci    CHECK(new_code_objects().empty());
1281cb0ef41Sopenharmony_ci    CHECK(new_allocation_sites().empty());
1291cb0ef41Sopenharmony_ci    CHECK(new_maps().empty());
1301cb0ef41Sopenharmony_ci    WeakenDescriptorArrays();
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  Rehash();
1341cb0ef41Sopenharmony_ci  CHECK(new_off_heap_array_buffers().empty());
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  // TODO(leszeks): Figure out a better way of dealing with scripts.
1371cb0ef41Sopenharmony_ci  CHECK_EQ(new_scripts().size(), 1);
1381cb0ef41Sopenharmony_ci  for (Handle<Script> script : new_scripts()) {
1391cb0ef41Sopenharmony_ci    // Assign a new script id to avoid collision.
1401cb0ef41Sopenharmony_ci    script->set_id(isolate()->GetNextScriptId());
1411cb0ef41Sopenharmony_ci    LogScriptEvents(*script);
1421cb0ef41Sopenharmony_ci    deserialized_scripts->push_back(
1431cb0ef41Sopenharmony_ci        isolate()->heap()->NewPersistentHandle(script));
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  return scope.CloseAndEscape(result);
1471cb0ef41Sopenharmony_ci}
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci}  // namespace internal
1501cb0ef41Sopenharmony_ci}  // namespace v8
151