Skip to content

Commit

Permalink
[vm] Support testing assembly snapshots for ARM.
Browse files Browse the repository at this point in the history
We have had several bugs propagate to Flutter end-users due to our lack of testing of
AOT Assembly snapshots on ARM (SIMARM_X64 in particular), causing reverts of SDK commits
and disrupting the Dart -> Flutter roll.

This leverages our custom ELF loader to load the generated ELF objects, which cannot be
loaded by dlopen() because they are marked with the ARM ABI.

For example, see:
  - flutter/flutter#40114
  - flutter/flutter#41228

Also do some tree-shaking of the snapshot writers for dart_precompiled_runtime.

Fixes #38433.

Change-Id: I5990769c623b8a13131b1848349af2c0a026272b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118569
Reviewed-by: Clement Skau <cskau@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
  • Loading branch information
sjindel-google authored and commit-bot@chromium.org committed Sep 25, 2019
1 parent a2803a1 commit 9a683de
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 30 deletions.
10 changes: 7 additions & 3 deletions pkg/test_runner/lib/src/compiler_configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,12 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration

bool get _isArm => _configuration.architecture == Architecture.arm;

bool get _isSimArm => _configuration.architecture == Architecture.simarm;

bool get _isArm64 => _configuration.architecture == Architecture.arm64;

bool get _isSimArm64 => _configuration.architecture == Architecture.simarm64;

bool get _isX64 => _configuration.architecture == Architecture.x64;

bool get _isIA32 => _configuration.architecture == Architecture.ia32;
Expand Down Expand Up @@ -701,12 +705,12 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration
Command computeAssembleCommand(String tempDir, List arguments,
Map<String, String> environmentOverrides) {
String cc, shared, ldFlags;
if (_isAndroid) {
if (_isAndroid || _isSimArm || _isSimArm64) {
var ndk = "third_party/android_tools/ndk";
String triple;
if (_isArm) {
if (_isArm || _isSimArm) {
triple = "arm-linux-androideabi";
} else if (_isArm64) {
} else if (_isArm64 || _isSimArm64) {
triple = "aarch64-linux-android";
}
String host;
Expand Down
9 changes: 3 additions & 6 deletions runtime/bin/elf_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class LoadedElf {
bool ReadSectionStringTable();
bool ReadSections();

static uword PageSize();
static uword PageSize() { return VirtualMemory::PageSize(); }

// Unlike File::Map, allows non-aligned 'start' and 'length'.
MappedMemory* MapFilePiece(uword start,
Expand Down Expand Up @@ -112,12 +112,9 @@ class LoadedElf {
return false; \
}

uword LoadedElf::PageSize() {
static uword page_size_ = VirtualMemory::CalculatePageSize();
return page_size_;
}

bool LoadedElf::Load() {
VirtualMemory::Init();

if (error_ != nullptr) {
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion runtime/include/dart_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,8 @@ DART_EXPORT void Dart_ExitIsolate();
* the vm isolate on startup and fast initialization of an isolate.
* A Snapshot of the heap is created before any dart code has executed.
*
* Requires there to be a current isolate.
* Requires there to be a current isolate. Not available in the precompiled
* runtime (check Dart_IsPrecompiledRuntime).
*
* \param buffer Returns a pointer to a buffer containing the
* snapshot. This buffer is scope allocated and is only valid
Expand Down
16 changes: 9 additions & 7 deletions runtime/vm/clustered_snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void Deserializer::InitializeHeader(RawObject* raw,
#endif
}

#if !defined(DART_PRECOMPILED_RUNTIME)
void SerializationCluster::WriteAndMeasureAlloc(Serializer* serializer) {
if (LOG_SECTION_BOUNDARIES) {
OS::PrintErr("Data + %" Px ": Alloc %s\n", serializer->bytes_written(),
Expand All @@ -115,7 +116,6 @@ void SerializationCluster::WriteAndMeasureFill(Serializer* serializer) {
size_ += (stop - start);
}

#if !defined(DART_PRECOMPILED_RUNTIME)
class ClassSerializationCluster : public SerializationCluster {
public:
explicit ClassSerializationCluster(intptr_t num_cids)
Expand Down Expand Up @@ -4336,6 +4336,10 @@ class FakeSerializationCluster : public SerializationCluster {
};
#endif // !DART_PRECOMPILED_RUNTIME

#if defined(DEBUG)
static const int32_t kSectionMarker = 0xABAB;
#endif

Serializer::Serializer(Thread* thread,
Snapshot::Kind kind,
uint8_t** buffer,
Expand Down Expand Up @@ -4551,6 +4555,7 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
#endif // !DART_PRECOMPILED_RUNTIME
}

#if !defined(DART_PRECOMPILED_RUNTIME)
void Serializer::WriteInstructions(RawInstructions* instr, RawCode* code) {
ASSERT(code != Code::null());

Expand Down Expand Up @@ -4740,11 +4745,6 @@ void Serializer::WriteVersionAndFeatures(bool is_vm_snapshot) {
free(const_cast<char*>(expected_features));
}

#if defined(DEBUG)
static const int32_t kSectionMarker = 0xABAB;
#endif

#if !defined(DART_PRECOMPILED_RUNTIME)
static int CompareClusters(SerializationCluster* const* a,
SerializationCluster* const* b) {
if ((*a)->size() > (*b)->size()) {
Expand All @@ -4755,7 +4755,6 @@ static int CompareClusters(SerializationCluster* const* a,
return 0;
}
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)

void Serializer::Serialize() {
while (stack_.length() > 0) {
Expand Down Expand Up @@ -5019,6 +5018,7 @@ void Serializer::WriteIsolateSnapshot(intptr_t num_base_objects,

heap_->ResetObjectIdTable();
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)

Deserializer::Deserializer(Thread* thread,
Snapshot::Kind kind,
Expand Down Expand Up @@ -5519,6 +5519,7 @@ DEFINE_FLAG(charp,
"Write a snapshot profile in V8 format to a file.");
#endif

#if !defined(DART_PRECOMPILED_RUNTIME)
FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
uint8_t** vm_snapshot_data_buffer,
uint8_t** isolate_snapshot_data_buffer,
Expand Down Expand Up @@ -5655,6 +5656,7 @@ void FullSnapshotWriter::WriteFullSnapshot() {
}
#endif
}
#endif // defined(DART_PRECOMPILED_RUNTIME)

FullSnapshotReader::FullSnapshotReader(const Snapshot* snapshot,
const uint8_t* instructions_buffer,
Expand Down
6 changes: 6 additions & 0 deletions runtime/vm/dart_api_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1627,19 +1627,24 @@ DART_EXPORT void Dart_ExitIsolate() {
Thread::ExitIsolate();
}

#if !defined(DART_PRECOMPILED_RUNTIME)
static uint8_t* ApiReallocate(uint8_t* ptr,
intptr_t old_size,
intptr_t new_size) {
return Api::TopScope(Thread::Current())
->zone()
->Realloc<uint8_t>(ptr, old_size, new_size);
}
#endif

DART_EXPORT Dart_Handle
Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
intptr_t* vm_snapshot_data_size,
uint8_t** isolate_snapshot_data_buffer,
intptr_t* isolate_snapshot_data_size) {
#if defined(DART_PRECOMPILED_RUNTIME)
return Api::NewError("Cannot create snapshots on an AOT runtime.");
#else
DARTSCOPE(Thread::Current());
API_TIMELINE_DURATION(T);
Isolate* I = T->isolate();
Expand Down Expand Up @@ -1676,6 +1681,7 @@ Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
}
*isolate_snapshot_data_size = writer.IsolateSnapshotSize();
return Api::Success();
#endif
}

DART_EXPORT bool Dart_IsKernel(const uint8_t* buffer, intptr_t buffer_size) {
Expand Down
12 changes: 9 additions & 3 deletions runtime/vm/image_snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "platform/assert.h"
#include "vm/compiler/backend/code_statistics.h"
#include "vm/compiler/runtime_api.h"
#include "vm/dwarf.h"
#include "vm/elf.h"
#include "vm/hash.h"
Expand Down Expand Up @@ -80,6 +81,7 @@ bool ObjectOffsetTrait::IsKeyEqual(Pair pair, Key key) {
reinterpret_cast<const void*>(body_b), body_size);
}

#if !defined(DART_PRECOMPILED_RUNTIME)
ImageWriter::ImageWriter(Heap* heap,
const void* shared_objects,
const void* shared_instructions,
Expand Down Expand Up @@ -677,7 +679,8 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
text_offset += WriteByteSequence(beginning, entry);
#endif // defined(IS_SIMARM_X64)

ASSERT((text_offset - instr_start) == insns.HeaderSize());
ASSERT((text_offset - instr_start) ==
compiler::target::Instructions::HeaderSize());
}

// 2. Write a label at the entry point.
Expand Down Expand Up @@ -753,9 +756,9 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
#else
text_offset += WriteByteSequence(entry, end);
#endif
ASSERT(kWordSize != compiler::target::kWordSize ||
(text_offset - instr_start) == insns.raw()->HeapSize());
}

ASSERT((text_offset - instr_start) == insns.raw()->HeapSize());
}

FrameUnwindEpilogue();
Expand Down Expand Up @@ -1081,6 +1084,7 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
}
#endif
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)

ImageReader::ImageReader(const uint8_t* data_image,
const uint8_t* instructions_image,
Expand Down Expand Up @@ -1144,6 +1148,7 @@ RawObject* ImageReader::GetSharedObjectAt(uint32_t offset) const {
return result;
}

#if !defined(DART_PRECOMPILED_RUNTIME)
void DropCodeWithoutReusableInstructions(const void* reused_instructions) {
class DropCodeVisitor : public FunctionVisitor, public ClassVisitor {
public:
Expand Down Expand Up @@ -1243,5 +1248,6 @@ void DropCodeWithoutReusableInstructions(const void* reused_instructions) {
ProgramVisitor::VisitClasses(&visitor);
ProgramVisitor::VisitFunctions(&visitor);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)

} // namespace dart
8 changes: 3 additions & 5 deletions runtime/vm/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -4799,11 +4799,9 @@ class Instructions : public Object {
}

static intptr_t HeaderSize() {
intptr_t alignment = OS::PreferredCodeAlignment();
intptr_t aligned_size = Utils::RoundUp(sizeof(RawInstructions), alignment);
#if !defined(IS_SIMARM_X64)
ASSERT(aligned_size == alignment);
#endif // !defined(IS_SIMARM_X64)
const intptr_t alignment = OS::PreferredCodeAlignment();
const intptr_t aligned_size =
Utils::RoundUp(sizeof(RawInstructions), alignment);
return aligned_size;
}

Expand Down
5 changes: 2 additions & 3 deletions runtime/vm/virtual_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@ class VirtualMemory {
return page_size_;
}

// Use only if Init() might not have been called.
static intptr_t CalculatePageSize();

static bool InSamePage(uword address0, uword address1);

// Truncate this virtual memory segment.
Expand All @@ -79,6 +76,8 @@ class VirtualMemory {
static VirtualMemory* ForImagePage(void* pointer, uword size);

private:
static intptr_t CalculatePageSize();

// Free a sub segment. On operating systems that support it this
// can give back the virtual memory to the system. Returns true on success.
static void FreeSubSegment(void* address, intptr_t size);
Expand Down
5 changes: 5 additions & 0 deletions runtime/vm/virtual_memory_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ intptr_t VirtualMemory::CalculatePageSize() {
}

void VirtualMemory::Init() {
if (page_size_ != 0) {
// Already initialized.
return;
}

page_size_ = CalculatePageSize();

#if defined(DUAL_MAPPING_SUPPORTED)
Expand Down
8 changes: 6 additions & 2 deletions tools/bots/test_matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,11 @@
"options": {
"use-blobs": true
}},
"dartkp-(linux|win|mac)-(debug|product|release)-(simarm|simarm64)-crossword": {
"dartkp-linux-(debug|product|release)-(simarm|simarm64)-crossword": {
"options": {
"builder-tag": "crossword"
}},
"dartkp-(win|mac)-(debug|product|release)-(simarm|simarm64)-crossword": {
"options": {
"builder-tag": "crossword",
"use-blobs": true
Expand Down Expand Up @@ -2274,7 +2278,7 @@
},
{
"builders": [
"vm-kernel-precomp-mac-debug-simarm_x64",
"vm-kernel-precomp-linux-debug-simarm_x64",
"vm-kernel-precomp-mac-release-simarm_x64"
],
"meta": {
Expand Down

0 comments on commit 9a683de

Please sign in to comment.