#include "src/snapshot/startup-deserializer.h"
#include "src/api/api.h"
#include "src/codegen/flush-instruction-cache.h"
#include "src/execution/v8threads.h"
#include "src/handles/handles-inl.h"
#include "src/heap/paged-spaces-inl.h"
#include "src/logging/counters-scopes.h"
#include "src/logging/log.h"
#include "src/objects/oddball.h"
#include "src/roots/roots-inl.h"
namespace v8 {
namespace internal {
void StartupDeserializer::DeserializeIntoIsolate() {
TRACE_EVENT0("v8", "V8.DeserializeIsolate");
RCS_SCOPE(isolate(), RuntimeCallCounterId::kDeserializeIsolate);
base::ElapsedTimer timer;
if (V8_UNLIKELY(v8_flags.profile_deserialization)) timer.Start();
NestedTimedHistogramScope histogram_timer(
isolate()->counters()->snapshot_deserialize_isolate());
HandleScope scope(isolate());
DCHECK_NULL(isolate()->thread_manager()->FirstThreadStateInUse());
DCHECK(isolate()->handle_scope_implementer()->blocks()->empty());
DCHECK(isolate()->startup_object_cache()->empty());
DCHECK(!isolate()->builtins()->is_initialized());
{
DeserializeAndCheckExternalReferenceTable();
isolate()->heap()->IterateSmiRoots(this);
isolate()->heap()->IterateRoots(
this,
base::EnumSet<SkipRoot>{SkipRoot::kUnserializable, SkipRoot::kWeak,
SkipRoot::kTracedHandles});
IterateStartupObjectCache(isolate(), this);
isolate()->heap()->IterateWeakRoots(
this, base::EnumSet<SkipRoot>{SkipRoot::kUnserializable});
DeserializeDeferredObjects();
if (USE_SIMULATOR_BOOL) {
for (DirectHandle<AccessorInfo> info : accessor_infos()) {
info->RestoreCallbackRedirectionAfterDeserialization(isolate());
}
for (DirectHandle<InterceptorInfo> info : interceptor_infos()) {
info->RestoreCallbackRedirectionAfterDeserialization(isolate());
}
for (DirectHandle<FunctionTemplateInfo> info :
function_template_infos()) {
info->RestoreCallbackRedirectionAfterDeserialization(isolate());
}
}
FlushICache();
}
isolate()->heap()->set_native_contexts_list(
ReadOnlyRoots(isolate()).undefined_value());
if (isolate()->heap()->allocation_sites_list() == Smi::zero()) {
isolate()->heap()->set_allocation_sites_list(
ReadOnlyRoots(isolate()).undefined_value());
}
isolate()->heap()->set_dirty_js_finalization_registries_list(
ReadOnlyRoots(isolate()).undefined_value());
isolate()->heap()->set_dirty_js_finalization_registries_list_tail(
ReadOnlyRoots(isolate()).undefined_value());
isolate()->builtins()->MarkInitialized();
LogNewMapEvents();
WeakenDescriptorArrays();
if (should_rehash()) {
Rehash();
}
if (V8_UNLIKELY(v8_flags.profile_deserialization)) {
const int bytes = source()->length();
const double ms = timer.Elapsed().InMillisecondsF();
PrintF("[Deserializing isolate (%d bytes) took %0.3f ms]\n", bytes, ms);
}
}
void StartupDeserializer::DeserializeAndCheckExternalReferenceTable() {
ExternalReferenceTable* table = isolate()->external_reference_table();
while (true) {
uint32_t index = source()->GetUint30();
if (index == ExternalReferenceTable::kSizeIsolateIndependent) break;
uint32_t encoded_index = source()->GetUint30();
CHECK_EQ(table->address(index), table->address(encoded_index));
}
}
void StartupDeserializer::LogNewMapEvents() {
if (v8_flags.log_maps) LOG(isolate(), LogAllMaps());
}
void StartupDeserializer::FlushICache() {
DCHECK(!deserializing_user_code());
for (PageMetadata* p : *isolate()->heap()->code_space()) {
FlushInstructionCache(p->area_start(), p->area_end() - p->area_start());
}
}
}
}