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