diff --git a/runtime/tools/bin_to_coff.py b/runtime/tools/bin_to_coff.py index c8a8ebc2a8b..1925bcdb9b2 100644 --- a/runtime/tools/bin_to_coff.py +++ b/runtime/tools/bin_to_coff.py @@ -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. diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index db497033cf0..a95642a7239 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc @@ -511,13 +511,25 @@ static uint8_t* malloc_allocator(uint8_t* ptr, return reinterpret_cast(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) { diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index 19395545e4e..a5958d62660 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc @@ -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(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(str->IsCanonical()); + intptr_t hash = String::GetCachedHash(str); + s->Write(hash); + s->WriteBytes(str->ptr()->data(), length); + } + } + + private: + GrowableArray 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(d->Ref(id)); + intptr_t length = d->ReadUnsigned(); + bool is_canonical = d->Read(); + Deserializer::InitializeHeader(str, kOneByteStringCid, + OneByteString::InstanceSize(length), + is_canonical); + str->ptr()->length_ = Smi::New(length); + String::SetCachedHash(str, d->Read()); + for (intptr_t j = 0; j < length; j++) { + str->ptr()->data()[j] = d->Read(); + } + } + } +}; + +#if !defined(DART_PRECOMPILED_RUNTIME) +class TwoByteStringSerializationCluster : public SerializationCluster { + public: + TwoByteStringSerializationCluster() : SerializationCluster("TwoByteString") {} + ~TwoByteStringSerializationCluster() {} + + void Trace(Serializer* s, RawObject* object) { + RawTwoByteString* str = reinterpret_cast(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(str->IsCanonical()); + intptr_t hash = String::GetCachedHash(str); + s->Write(hash); + s->WriteBytes(reinterpret_cast(str->ptr()->data()), length * 2); + } + } + + private: + GrowableArray 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(d->Ref(id)); + intptr_t length = d->ReadUnsigned(); + bool is_canonical = d->Read(); + Deserializer::InitializeHeader(str, kTwoByteStringCid, + TwoByteString::InstanceSize(length), + is_canonical); + str->ptr()->length_ = Smi::New(length); + String::SetCachedHash(str, d->Read()); + uint8_t* cdata = reinterpret_cast(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); } diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index 59f903a7316..0463a15c93f 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -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 } diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 4b259aa46c3..4c62313318d 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -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(); diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc index 03672dc2195..c097744bf69 100644 --- a/runtime/vm/image_snapshot.cc +++ b/runtime/vm/image_snapshot.cc @@ -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; diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index fc8dfc7dd18..0c88bdc4900 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -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; }; diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index 5c3b68eb850..1f7beaa843f 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h @@ -196,6 +196,9 @@ class Snapshot { const uint8_t* Addr() const { return reinterpret_cast(this); } const uint8_t* DataImage() const { + if (!IncludesCode(kind())) { + return NULL; + } uword offset = Utils::RoundUp(length(), OS::kMaxPreferredCodeAlignment); return Addr() + offset; } diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index 3da6666b132..e05f4757042 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -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 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( - 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.