Revert "[vm, snapshot] Use data image pages for kFull snapshots."

This reverts commit c8f3f132ad.

Revert "[vm] Fix CoreSnapshotSize and StandaloneSnapshotSize to account for the image page size."

This reverts commit 1d6ab52f38.

Bug: b/140791872
Change-Id: I34c42310e3ec4a09048967f34a0e1ddc6a67ea93
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/116688
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2019-09-10 23:52:52 +00:00 committed by commit-bot@chromium.org
parent 5303538a09
commit 03b195164b
9 changed files with 302 additions and 148 deletions

View file

@ -4,8 +4,6 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# See also "PE Format" at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
import argparse
from ctypes import create_string_buffer
from struct import *
@ -21,7 +19,6 @@ FILE_HEADER_AR32WR = 0x100 # File is 32-bit little endian
SECTION_HEADER_TEXT = 0x20 # Contains executable code
SECTION_HEADER_DATA = 0x40 # Contains only initialized data
SECTION_HEADER_BSS = 0x80 # Contains uninitialized data
SECTION_HEADER_ALIGN_32BYTES = 0x600000
# FILE HEADER FORMAT
# typedef struct {
@ -179,18 +176,17 @@ def main():
offset += FILE_HEADER_SIZE
section_name = SECTION_NAME_RODATA
section_flags = SECTION_HEADER_DATA
section_type = SECTION_HEADER_DATA
if args.executable:
section_name = SECTION_NAME_TEXT
section_flags = SECTION_HEADER_TEXT
section_flags |= SECTION_HEADER_ALIGN_32BYTES
section_type = SECTION_HEADER_TEXT
# Populate the section header for a single section.
pack_into(SECTION_HEADER_FORMAT, buff, offset, section_name, SECTION_PADDR,
SECTION_VADDR, section_size + size_symbol_size,
SECTION_RAW_DATA_PTR, SECTION_RELOCATION_PTR,
SECTION_LINE_NUMS_PTR, SECTION_NUM_RELOCATION,
SECTION_NUM_LINE_NUMS, section_flags)
SECTION_NUM_LINE_NUMS, section_type)
offset += SECTION_HEADER_SIZE
# Copy the binary data.

View file

@ -511,13 +511,25 @@ static uint8_t* malloc_allocator(uint8_t* ptr,
return reinterpret_cast<uint8_t*>(realloc(ptr, new_size));
}
// Start an Isolate, load a script and create a full snapshot.
static void BenchmarkSnapshotSize(Benchmark* benchmark, const char* script) {
BENCHMARK_SIZE(CoreSnapshotSize) {
const char* kScriptChars =
"import 'dart:async';\n"
"import 'dart:core';\n"
"import 'dart:collection';\n"
"import 'dart:_internal';\n"
"import 'dart:math';\n"
"import 'dart:isolate';\n"
"import 'dart:mirrors';\n"
"import 'dart:typed_data';\n"
"\n";
// Start an Isolate, load a script and create a full snapshot.
uint8_t* vm_snapshot_data_buffer;
uint8_t* isolate_snapshot_data_buffer;
// Need to load the script into the dart: core library due to
// the import of dart:_internal.
TestCase::LoadCoreTestScript(script, nullptr);
TestCase::LoadCoreTestScript(kScriptChars, NULL);
Thread* thread = Thread::Current();
TransitionNativeToVM transition(thread);
StackZone zone(thread);
HANDLESCOPE(thread);
@ -525,63 +537,58 @@ static void BenchmarkSnapshotSize(Benchmark* benchmark, const char* script) {
Api::CheckAndFinalizePendingClasses(thread);
// Write snapshot with object content.
uint8_t* vm_snapshot_data_buffer = nullptr;
uint8_t* isolate_snapshot_data_buffer = nullptr;
uint8_t* vm_snapshot_text_buffer = nullptr;
uint8_t* isolate_snapshot_text_buffer = nullptr;
BlobImageWriter vm_image_writer(thread, &vm_snapshot_text_buffer,
&malloc_allocator, 2 * MB /* initial_size */,
/*shared_objects=*/nullptr,
/*shared_instructions=*/nullptr,
/*reused_instructions=*/nullptr);
BlobImageWriter isolate_image_writer(thread, &isolate_snapshot_text_buffer,
&malloc_allocator,
2 * MB /* initial_size */,
/*shared_objects=*/nullptr,
/*shared_instructions=*/nullptr,
/*reused_instructions=*/nullptr);
FullSnapshotWriter writer(Snapshot::kFull, &vm_snapshot_data_buffer,
&isolate_snapshot_data_buffer, &malloc_allocator,
&vm_image_writer, &isolate_image_writer);
NULL, NULL /* image_writer */);
writer.WriteFullSnapshot();
const Snapshot* snapshot =
Snapshot::SetupFromBuffer(isolate_snapshot_data_buffer);
ASSERT(snapshot->kind() == Snapshot::kFull);
benchmark->set_score(writer.IsolateSnapshotSize() +
isolate_image_writer.data_size());
benchmark->set_score(snapshot->length());
free(vm_snapshot_data_buffer);
free(vm_snapshot_text_buffer);
free(isolate_snapshot_data_buffer);
free(isolate_snapshot_text_buffer);
}
BENCHMARK_SIZE(CoreSnapshotSize) {
BenchmarkSnapshotSize(benchmark,
"import 'dart:async';\n"
"import 'dart:core';\n"
"import 'dart:collection';\n"
"import 'dart:_internal';\n"
"import 'dart:math';\n"
"import 'dart:isolate';\n"
"import 'dart:mirrors';\n"
"import 'dart:typed_data';\n"
"\n");
}
BENCHMARK_SIZE(StandaloneSnapshotSize) {
BenchmarkSnapshotSize(benchmark,
"import 'dart:async';\n"
"import 'dart:core';\n"
"import 'dart:collection';\n"
"import 'dart:convert';\n"
"import 'dart:math';\n"
"import 'dart:isolate';\n"
"import 'dart:mirrors';\n"
"import 'dart:typed_data';\n"
"import 'dart:io';\n"
"import 'dart:cli';\n"
"\n");
const char* kScriptChars =
"import 'dart:async';\n"
"import 'dart:core';\n"
"import 'dart:collection';\n"
"import 'dart:convert';\n"
"import 'dart:math';\n"
"import 'dart:isolate';\n"
"import 'dart:mirrors';\n"
"import 'dart:typed_data';\n"
"import 'dart:io';\n"
"import 'dart:cli';\n"
"\n";
// Start an Isolate, load a script and create a full snapshot.
uint8_t* vm_snapshot_data_buffer;
uint8_t* isolate_snapshot_data_buffer;
// Need to load the script into the dart: core library due to
// the import of dart:_internal.
TestCase::LoadCoreTestScript(kScriptChars, NULL);
TransitionNativeToVM transition(thread);
StackZone zone(thread);
HANDLESCOPE(thread);
Api::CheckAndFinalizePendingClasses(thread);
// Write snapshot with object content.
FullSnapshotWriter writer(Snapshot::kFull, &vm_snapshot_data_buffer,
&isolate_snapshot_data_buffer, &malloc_allocator,
NULL, NULL /* image_writer */);
writer.WriteFullSnapshot();
const Snapshot* snapshot =
Snapshot::SetupFromBuffer(isolate_snapshot_data_buffer);
ASSERT(snapshot->kind() == Snapshot::kFull);
benchmark->set_score(snapshot->length());
free(vm_snapshot_data_buffer);
free(isolate_snapshot_data_buffer);
}
BENCHMARK(CreateMirrorSystem) {

View file

@ -3305,6 +3305,19 @@ class MintDeserializationCluster : public DeserializationCluster {
}
void ReadFill(Deserializer* d) {}
void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
const Class& mint_cls =
Class::Handle(zone, Isolate::Current()->object_store()->mint_class());
mint_cls.set_constants(Object::empty_array());
Object& number = Object::Handle(zone);
for (intptr_t i = start_index_; i < stop_index_; i++) {
number = refs.At(i);
if (number.IsMint() && number.IsCanonical()) {
mint_cls.InsertCanonicalMint(zone, Mint::Cast(number));
}
}
}
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@ -4085,6 +4098,159 @@ class ArrayDeserializationCluster : public DeserializationCluster {
const intptr_t cid_;
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class OneByteStringSerializationCluster : public SerializationCluster {
public:
OneByteStringSerializationCluster() : SerializationCluster("OneByteString") {}
~OneByteStringSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
RawOneByteString* str = reinterpret_cast<RawOneByteString*>(object);
objects_.Add(str);
}
void WriteAlloc(Serializer* s) {
s->WriteCid(kOneByteStringCid);
intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawOneByteString* str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawOneByteString* str = objects_[i];
AutoTraceObject(str);
intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(str->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
s->Write<int32_t>(hash);
s->WriteBytes(str->ptr()->data(), length);
}
}
private:
GrowableArray<RawOneByteString*> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
class OneByteStringDeserializationCluster : public DeserializationCluster {
public:
OneByteStringDeserializationCluster() {}
~OneByteStringDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
OneByteString::InstanceSize(length)));
}
stop_index_ = d->next_index();
}
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kOneByteStringCid,
OneByteString::InstanceSize(length),
is_canonical);
str->ptr()->length_ = Smi::New(length);
String::SetCachedHash(str, d->Read<int32_t>());
for (intptr_t j = 0; j < length; j++) {
str->ptr()->data()[j] = d->Read<uint8_t>();
}
}
}
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class TwoByteStringSerializationCluster : public SerializationCluster {
public:
TwoByteStringSerializationCluster() : SerializationCluster("TwoByteString") {}
~TwoByteStringSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(object);
objects_.Add(str);
}
void WriteAlloc(Serializer* s) {
s->WriteCid(kTwoByteStringCid);
intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTwoByteString* str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawTwoByteString* str = objects_[i];
AutoTraceObject(str);
intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(str->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
s->Write<int32_t>(hash);
s->WriteBytes(reinterpret_cast<uint8_t*>(str->ptr()->data()), length * 2);
}
}
private:
GrowableArray<RawTwoByteString*> objects_;
};
#endif // !DART_PRECOMPILED_RUNTIME
class TwoByteStringDeserializationCluster : public DeserializationCluster {
public:
TwoByteStringDeserializationCluster() {}
~TwoByteStringDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
TwoByteString::InstanceSize(length)));
}
stop_index_ = d->next_index();
}
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kTwoByteStringCid,
TwoByteString::InstanceSize(length),
is_canonical);
str->ptr()->length_ = Smi::New(length);
String::SetCachedHash(str, d->Read<int32_t>());
uint8_t* cdata = reinterpret_cast<uint8_t*>(str->ptr()->data());
d->ReadBytes(cdata, length * 2);
}
}
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class FakeSerializationCluster : public SerializationCluster {
public:
@ -4205,10 +4371,16 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
if (Snapshot::IncludesCode(kind_)) {
switch (cid) {
case kPcDescriptorsCid:
return new (Z) RODataSerializationCluster("(RO)PcDescriptors", cid);
case kCodeSourceMapCid:
return new (Z) RODataSerializationCluster("(RO)CodeSourceMap", cid);
case kStackMapCid:
return new (Z) RODataSerializationCluster("(RO)StackMap", cid);
case kOneByteStringCid:
return new (Z) RODataSerializationCluster("(RO)OneByteString", cid);
case kTwoByteStringCid:
return new (Z) RODataSerializationCluster("(RO)TwoByteString", cid);
}
}
@ -4247,8 +4419,6 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
#endif // !DART_PRECOMPILED_RUNTIME
case kObjectPoolCid:
return new (Z) ObjectPoolSerializationCluster();
case kPcDescriptorsCid:
return new (Z) RODataSerializationCluster("(RO)PcDescriptors", cid);
case kExceptionHandlersCid:
return new (Z) ExceptionHandlersSerializationCluster();
case kContextCid:
@ -4298,9 +4468,9 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
case kImmutableArrayCid:
return new (Z) ArraySerializationCluster(kImmutableArrayCid);
case kOneByteStringCid:
return new (Z) RODataSerializationCluster("(RO)OneByteString", cid);
return new (Z) OneByteStringSerializationCluster();
case kTwoByteStringCid:
return new (Z) RODataSerializationCluster("(RO)TwoByteString", cid);
return new (Z) TwoByteStringSerializationCluster();
default:
break;
}
@ -4794,15 +4964,17 @@ Deserializer::Deserializer(Thread* thread,
zone_(thread->zone()),
kind_(kind),
stream_(buffer, size),
image_reader_(nullptr),
refs_(nullptr),
image_reader_(NULL),
refs_(NULL),
next_ref_index_(1),
clusters_(nullptr) {
ASSERT((instructions_buffer != nullptr) || !Snapshot::IncludesCode(kind));
ASSERT(data_buffer != nullptr);
image_reader_ =
new (zone_) ImageReader(data_buffer, instructions_buffer,
shared_data_buffer, shared_instructions_buffer);
clusters_(NULL) {
if (Snapshot::IncludesCode(kind)) {
ASSERT(instructions_buffer != NULL);
ASSERT(data_buffer != NULL);
image_reader_ =
new (zone_) ImageReader(data_buffer, instructions_buffer,
shared_data_buffer, shared_instructions_buffer);
}
stream_.SetPosition(offset);
}
@ -4915,14 +5087,25 @@ DeserializationCluster* Deserializer::ReadCluster() {
return new (Z) ArrayDeserializationCluster(kArrayCid);
case kImmutableArrayCid:
return new (Z) ArrayDeserializationCluster(kImmutableArrayCid);
case kOneByteStringCid:
case kTwoByteStringCid:
return new (Z) RODataDeserializationCluster();
case kOneByteStringCid: {
if (Snapshot::IncludesCode(kind_)) {
return new (Z) RODataDeserializationCluster();
} else {
return new (Z) OneByteStringDeserializationCluster();
}
}
case kTwoByteStringCid: {
if (Snapshot::IncludesCode(kind_)) {
return new (Z) RODataDeserializationCluster();
} else {
return new (Z) TwoByteStringDeserializationCluster();
}
}
default:
break;
}
FATAL1("No cluster defined for cid %" Pd, cid);
return nullptr;
return NULL;
}
RawApiError* Deserializer::VerifyImageAlignment() {
@ -5309,8 +5492,7 @@ FullSnapshotWriter::~FullSnapshotWriter() {}
intptr_t FullSnapshotWriter::WriteVMSnapshot() {
TIMELINE_DURATION(thread(), Isolate, "WriteVMSnapshot");
ASSERT(vm_snapshot_data_buffer_ != nullptr);
ASSERT(vm_image_writer_ != nullptr);
ASSERT(vm_snapshot_data_buffer_ != NULL);
Serializer serializer(thread(), kind_, vm_snapshot_data_buffer_, alloc_,
kInitialSize, vm_image_writer_, /*vm=*/true,
profile_writer_);
@ -5327,12 +5509,14 @@ intptr_t FullSnapshotWriter::WriteVMSnapshot() {
serializer.FillHeader(serializer.kind());
clustered_vm_size_ = serializer.bytes_written();
vm_image_writer_->SetProfileWriter(profile_writer_);
vm_image_writer_->Write(serializer.stream(), true);
mapped_data_size_ += vm_image_writer_->data_size();
mapped_text_size_ += vm_image_writer_->text_size();
vm_image_writer_->ResetOffsets();
vm_image_writer_->ClearProfileWriter();
if (Snapshot::IncludesCode(kind_)) {
vm_image_writer_->SetProfileWriter(profile_writer_);
vm_image_writer_->Write(serializer.stream(), true);
mapped_data_size_ += vm_image_writer_->data_size();
mapped_text_size_ += vm_image_writer_->text_size();
vm_image_writer_->ResetOffsets();
vm_image_writer_->ClearProfileWriter();
}
// The clustered part + the direct mapped data part.
vm_isolate_snapshot_size_ = serializer.bytes_written();
@ -5342,13 +5526,11 @@ intptr_t FullSnapshotWriter::WriteVMSnapshot() {
void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
TIMELINE_DURATION(thread(), Isolate, "WriteIsolateSnapshot");
ASSERT(isolate_snapshot_data_buffer_ != nullptr);
ASSERT(isolate_image_writer_ != nullptr);
Serializer serializer(thread(), kind_, isolate_snapshot_data_buffer_, alloc_,
kInitialSize, isolate_image_writer_, /*vm=*/false,
profile_writer_);
ObjectStore* object_store = isolate()->object_store();
ASSERT(object_store != nullptr);
ASSERT(object_store != NULL);
serializer.ReserveHeader();
serializer.WriteVersionAndFeatures(false);
@ -5358,16 +5540,18 @@ void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
serializer.FillHeader(serializer.kind());
clustered_isolate_size_ = serializer.bytes_written();
isolate_image_writer_->SetProfileWriter(profile_writer_);
isolate_image_writer_->Write(serializer.stream(), false);
if (Snapshot::IncludesCode(kind_)) {
isolate_image_writer_->SetProfileWriter(profile_writer_);
isolate_image_writer_->Write(serializer.stream(), false);
#if defined(DART_PRECOMPILER)
isolate_image_writer_->DumpStatistics();
isolate_image_writer_->DumpStatistics();
#endif
mapped_data_size_ += isolate_image_writer_->data_size();
mapped_text_size_ += isolate_image_writer_->text_size();
isolate_image_writer_->ResetOffsets();
isolate_image_writer_->ClearProfileWriter();
mapped_data_size_ += isolate_image_writer_->data_size();
mapped_text_size_ += isolate_image_writer_->text_size();
isolate_image_writer_->ResetOffsets();
isolate_image_writer_->ClearProfileWriter();
}
// The clustered part + the direct mapped data part.
isolate_snapshot_size_ = serializer.bytes_written();
@ -5488,11 +5672,11 @@ RawApiError* FullSnapshotReader::ReadVMSnapshot() {
return api_error;
}
ASSERT(data_image_ != nullptr);
thread_->isolate()->SetupImagePage(data_image_,
/* is_executable */ false);
if (Snapshot::IncludesCode(kind_)) {
ASSERT(instructions_image_ != nullptr);
ASSERT(data_image_ != NULL);
thread_->isolate()->SetupImagePage(data_image_,
/* is_executable */ false);
ASSERT(instructions_image_ != NULL);
thread_->isolate()->SetupImagePage(instructions_image_,
/* is_executable */ true);
}
@ -5519,18 +5703,18 @@ RawApiError* FullSnapshotReader::ReadIsolateSnapshot() {
return api_error;
}
ASSERT(data_image_ != nullptr);
thread_->isolate()->SetupImagePage(data_image_,
/* is_executable */ false);
if (Snapshot::IncludesCode(kind_)) {
ASSERT(instructions_image_ != nullptr);
ASSERT(data_image_ != NULL);
thread_->isolate()->SetupImagePage(data_image_,
/* is_executable */ false);
ASSERT(instructions_image_ != NULL);
thread_->isolate()->SetupImagePage(instructions_image_,
/* is_executable */ true);
if (shared_data_image_ != nullptr) {
if (shared_data_image_ != NULL) {
thread_->isolate()->SetupImagePage(shared_data_image_,
/* is_executable */ false);
}
if (shared_instructions_image_ != nullptr) {
if (shared_instructions_image_ != NULL) {
thread_->isolate()->SetupImagePage(shared_instructions_image_,
/* is_executable */ true);
}

View file

@ -858,14 +858,6 @@ const char* Dart::FeaturesString(Isolate* isolate,
#endif
#else
#error What architecture?
#endif
} else {
#if defined(ARCH_IS_32_BIT)
buffer.AddString(" 32-bit");
#elif defined(ARCH_IS_64_BIT)
buffer.AddString(" 64-bit");
#else
#error What word size?
#endif
}

View file

@ -1666,21 +1666,10 @@ Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
Symbols::Compact();
uint8_t* vm_snapshot_instruction_buffer = nullptr;
BlobImageWriter vm_image_writer(T, &vm_snapshot_instruction_buffer,
ApiReallocate, 2 * MB /* initial_size */,
/*shared_objects=*/nullptr,
/*shared_instructions=*/nullptr,
/*reused_instructions=*/nullptr);
uint8_t* isolate_snapshot_instruction_buffer = nullptr;
BlobImageWriter isolate_image_writer(T, &isolate_snapshot_instruction_buffer,
ApiReallocate, 2 * MB /* initial_size */,
/*shared_objects=*/nullptr,
/*shared_instructions=*/nullptr,
/*reused_instructions=*/nullptr);
FullSnapshotWriter writer(Snapshot::kFull, vm_snapshot_data_buffer,
isolate_snapshot_data_buffer, ApiReallocate,
&vm_image_writer, &isolate_image_writer);
NULL /* vm_image_writer */,
NULL /* isolate_image_writer */);
writer.WriteFullSnapshot();
if (vm_snapshot_data_buffer != NULL) {
*vm_snapshot_data_size = writer.VmIsolateSnapshotSize();

View file

@ -1090,6 +1090,7 @@ ImageReader::ImageReader(const uint8_t* data_image,
shared_data_image_(shared_data_image),
shared_instructions_image_(shared_instructions_image) {
ASSERT(data_image != NULL);
ASSERT(instructions_image != NULL);
}
RawApiError* ImageReader::VerifyAlignment() const {
@ -1106,7 +1107,6 @@ RawApiError* ImageReader::VerifyAlignment() const {
}
RawInstructions* ImageReader::GetInstructionsAt(int32_t offset) const {
ASSERT(instructions_image_ != nullptr);
ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
RawObject* result;

View file

@ -2140,6 +2140,10 @@ class RawString : public RawInstance {
private:
friend class Library;
friend class OneByteStringSerializationCluster;
friend class TwoByteStringSerializationCluster;
friend class OneByteStringDeserializationCluster;
friend class TwoByteStringDeserializationCluster;
friend class RODataSerializationCluster;
friend class ImageWriter;
};

View file

@ -196,6 +196,9 @@ class Snapshot {
const uint8_t* Addr() const { return reinterpret_cast<const uint8_t*>(this); }
const uint8_t* DataImage() const {
if (!IncludesCode(kind())) {
return NULL;
}
uword offset = Utils::RoundUp(length(), OS::kMaxPreferredCodeAlignment);
return Addr() + offset;
}

View file

@ -724,8 +724,7 @@ VM_UNIT_TEST_CASE(FullSnapshot) {
"}\n";
Dart_Handle result;
uint8_t* isolate_snapshot_data_buffer = nullptr;
intptr_t isolate_snapshot_data_size = 0;
uint8_t* isolate_snapshot_data_buffer;
// Start an Isolate, load a script and create a full snapshot.
Timer timer1(true, "Snapshot_test");
@ -750,38 +749,17 @@ VM_UNIT_TEST_CASE(FullSnapshot) {
OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
// Write snapshot with object content.
uint8_t* isolate_snapshot_text_buffer = nullptr;
BlobImageWriter image_writer(thread, &isolate_snapshot_text_buffer,
&malloc_allocator, 2 * MB /* initial_size */,
/*shared_objects=*/nullptr,
/*shared_instructions=*/nullptr,
/*reused_instructions=*/nullptr);
FullSnapshotWriter writer(Snapshot::kFull, nullptr,
FullSnapshotWriter writer(Snapshot::kFull, NULL,
&isolate_snapshot_data_buffer, &malloc_allocator,
nullptr, &image_writer);
NULL, /*image_writer*/ nullptr);
writer.WriteFullSnapshot();
isolate_snapshot_data_size = writer.IsolateSnapshotSize();
free(isolate_snapshot_text_buffer);
}
// Malloc gives only 8 byte alignment, but we need
// OS::kMaxPreferredCodeAlignment. Rellocate to VirtualMemory to get page
// alignment.
std::unique_ptr<VirtualMemory> aligned_isolate_snapshot_data_buffer(
VirtualMemory::Allocate(
Utils::RoundUp(isolate_snapshot_data_size, VirtualMemory::PageSize()),
false, "snapshot_test"));
memmove(aligned_isolate_snapshot_data_buffer->address(),
isolate_snapshot_data_buffer, isolate_snapshot_data_size);
free(isolate_snapshot_data_buffer);
isolate_snapshot_data_buffer = nullptr;
// Now Create another isolate using the snapshot and execute a method
// from the script.
Timer timer2(true, "Snapshot_test");
timer2.Start();
TestCase::CreateTestIsolateFromSnapshot(reinterpret_cast<uint8_t*>(
aligned_isolate_snapshot_data_buffer->address()));
TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_data_buffer);
{
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
timer2.Stop();
@ -794,6 +772,7 @@ VM_UNIT_TEST_CASE(FullSnapshot) {
Dart_ExitScope();
}
Dart_ShutdownIsolate();
free(isolate_snapshot_data_buffer);
}
// Helper function to call a top level Dart function and serialize the result.