Revert "[vm] AOT blobs snapshots are obsolete. Remove dead code."
This reverts commit bcc0900e6ac2fc971869153b2e825d9b7b77bda8.
Reason for revert: This CL is breaking the Fuchsia Flutter build see https://github.com/flutter/engine/pull/16604/checks?check_run_id=445155807
Original change's description:
> [vm] AOT blobs snapshots are obsolete. Remove dead code.
>
> Change-Id: I35cf4befbe66b92197dcd659172f90be3de30f8e
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134840
> Commit-Queue: Samir Jindel <sjindel@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
TBR=rmacnak@google.com,sjindel@google.com
Change-Id: I9dd32a71bf43907f59ed766b98bf453bab99ea3c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135881
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index b96782c..fdc14d2 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -259,6 +259,7 @@
isMinified: boolOption("minified"),
useAnalyzerCfe: boolOption("use-cfe"),
useAnalyzerFastaParser: boolOption("analyzer-use-fasta-parser"),
+ useBlobs: boolOption("use-blobs"),
useElf: boolOption("use-elf"),
useHotReload: boolOption("hot-reload"),
useHotReloadRollback: boolOption("hot-reload-rollback"),
@@ -329,6 +330,8 @@
final bool useAnalyzerCfe;
final bool useAnalyzerFastaParser;
+ // TODO(rnystrom): What is this?
+ final bool useBlobs;
final bool useElf;
final bool useHotReload;
@@ -356,6 +359,7 @@
bool isMinified,
bool useAnalyzerCfe,
bool useAnalyzerFastaParser,
+ bool useBlobs,
bool useElf,
bool useHotReload,
bool useHotReloadRollback,
@@ -377,6 +381,7 @@
isMinified = isMinified ?? false,
useAnalyzerCfe = useAnalyzerCfe ?? false,
useAnalyzerFastaParser = useAnalyzerFastaParser ?? false,
+ useBlobs = useBlobs ?? false,
useElf = useElf ?? false,
useHotReload = useHotReload ?? false,
useHotReloadRollback = useHotReloadRollback ?? false,
@@ -407,6 +412,7 @@
isMinified == other.isMinified &&
useAnalyzerCfe == other.useAnalyzerCfe &&
useAnalyzerFastaParser == other.useAnalyzerFastaParser &&
+ useBlobs == other.useBlobs &&
useElf == other.useElf &&
useHotReload == other.useHotReload &&
useHotReloadRollback == other.useHotReloadRollback &&
@@ -456,6 +462,7 @@
isMinified,
useAnalyzerCfe,
useAnalyzerFastaParser,
+ useBlobs,
useElf,
useHotReload,
useHotReloadRollback,
@@ -496,6 +503,7 @@
if (isMinified) fields.add("minified");
if (useAnalyzerCfe) fields.add("use-cfe");
if (useAnalyzerFastaParser) fields.add("analyzer-use-fasta-parser");
+ if (useBlobs) fields.add("use-blobs");
if (useHotReload) fields.add("hot-reload");
if (useHotReloadRollback) fields.add("hot-reload-rollback");
if (useSdk) fields.add("use-sdk");
@@ -553,6 +561,7 @@
boolField("use-cfe", useAnalyzerCfe, other.useAnalyzerCfe);
boolField("analyzer-use-fasta-parser", useAnalyzerFastaParser,
other.useAnalyzerFastaParser);
+ boolField("use-blobs", useBlobs, other.useBlobs);
boolField("host-checked", isHostChecked, other.isHostChecked);
boolField("hot-reload", useHotReload, other.useHotReload);
boolField("hot-reload-rollback", useHotReloadRollback,
diff --git a/pkg/smith/test/configuration_test.dart b/pkg/smith/test/configuration_test.dart
index d558cc2..bf2c631 100644
--- a/pkg/smith/test/configuration_test.dart
+++ b/pkg/smith/test/configuration_test.dart
@@ -382,6 +382,7 @@
isMinified: true,
useAnalyzerCfe: true,
useAnalyzerFastaParser: true,
+ useBlobs: true,
useElf: true,
useHotReload: true,
useHotReloadRollback: true,
@@ -411,6 +412,7 @@
minified: false true
use-cfe: false true
analyzer-use-fasta-parser: false true
+ use-blobs: false true
host-checked: false true
hot-reload: false true
hot-reload-rollback: false true
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index 7ea9107..938d48c 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -547,6 +547,7 @@
final String processTestFilename;
final String precompiledTestDirectory;
final List<String> arguments;
+ final bool useBlobs;
final bool useElf;
final List<String> extraLibraries;
@@ -555,6 +556,7 @@
this.processTestFilename,
this.precompiledTestDirectory,
this.arguments,
+ this.useBlobs,
this.useElf,
this.extraLibraries,
{int index = 0})
@@ -565,6 +567,7 @@
processTestFilename,
precompiledTestDirectory,
arguments,
+ useBlobs,
useElf,
extraLibraries,
index: index);
@@ -579,6 +582,7 @@
builder.add(buildPath);
builder.add(precompiledTestDirectory);
builder.add(arguments);
+ builder.add(useBlobs);
builder.add(useElf);
extraLibraries.forEach(builder.add);
}
@@ -586,6 +590,7 @@
bool _equal(AdbPrecompilationCommand other) =>
super._equal(other) &&
buildPath == other.buildPath &&
+ useBlobs == other.useBlobs &&
useElf == other.useElf &&
arguments == other.arguments &&
precompiledTestDirectory == other.precompiledTestDirectory &&
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index fd48df2..90b6dcd 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -626,7 +626,7 @@
tempDir, arguments, environmentOverrides));
}
- if (!_configuration.useElf) {
+ if (!_configuration.useBlobs && !_configuration.useElf) {
commands.add(
computeAssembleCommand(tempDir, arguments, environmentOverrides));
if (!_configuration.keepGeneratedFiles) {
@@ -698,7 +698,10 @@
}
var args = [
- if (_configuration.useElf) ...[
+ if (_configuration.useBlobs) ...[
+ "--snapshot-kind=app-aot-blobs",
+ "--blobs_container_filename=$tempDir/out.aotsnapshot"
+ ] else if (_configuration.useElf) ...[
"--snapshot-kind=app-aot-elf",
"--elf=$tempDir/out.aotsnapshot"
] else ...[
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index 63fc701..4982613 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -115,6 +115,7 @@
bool get isMinified => configuration.isMinified;
bool get useAnalyzerCfe => configuration.useAnalyzerCfe;
bool get useAnalyzerFastaParser => configuration.useAnalyzerFastaParser;
+ bool get useBlobs => configuration.useBlobs;
bool get useElf => configuration.useElf;
bool get useSdk => configuration.useSdk;
bool get enableAsserts => configuration.enableAsserts;
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 95f9217..09a824c 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -816,6 +816,7 @@
useAnalyzerCfe: data["use_cfe"] as bool,
useAnalyzerFastaParser:
data["analyzer_use_fasta_parser"] as bool,
+ useBlobs: data["use_blobs"] as bool,
useElf: data["use_elf"] as bool,
useSdk: data["use_sdk"] as bool,
useHotReload: data["hot_reload"] as bool,
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 1bb10ab..05fbe2b 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -48,10 +48,12 @@
case Runtime.dartPrecompiled:
if (configuration.system == System.android) {
return DartPrecompiledAdbRuntimeConfiguration(
+ useBlobs: configuration.useBlobs,
useElf: configuration.useElf,
);
} else {
return DartPrecompiledRuntimeConfiguration(
+ useBlobs: configuration.useBlobs,
useElf: configuration.useElf,
);
}
@@ -280,8 +282,11 @@
}
class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
+ final bool useBlobs;
final bool useElf;
- DartPrecompiledRuntimeConfiguration({bool useElf}) : useElf = useElf;
+ DartPrecompiledRuntimeConfiguration({bool useBlobs, bool useElf})
+ : useBlobs = useBlobs,
+ useElf = useElf;
List<Command> computeRuntimeCommands(
CommandArtifact artifact,
@@ -335,8 +340,11 @@
static const deviceDir = '/data/local/tmp/precompilation-testing';
static const deviceTestDir = '/data/local/tmp/precompilation-testing/test';
+ final bool useBlobs;
final bool useElf;
- DartPrecompiledAdbRuntimeConfiguration({bool useElf}) : useElf = useElf;
+ DartPrecompiledAdbRuntimeConfiguration({bool useBlobs, bool useElf})
+ : useBlobs = useBlobs,
+ useElf = useElf;
List<Command> computeRuntimeCommands(
CommandArtifact artifact,
@@ -353,7 +361,7 @@
var processTest = processTestBinaryFileName;
return [
AdbPrecompilationCommand(
- buildDir, processTest, script, arguments, useElf, extraLibs)
+ buildDir, processTest, script, arguments, useBlobs, useElf, extraLibs)
];
}
}
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 568fa5f..93db88b 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -81,6 +81,7 @@
kCoreJIT,
kApp,
kAppJIT,
+ kAppAOTBlobs,
kAppAOTAssembly,
kAppAOTElf,
kVMAOTAssembly,
@@ -94,6 +95,7 @@
"core-jit",
"app",
"app-jit",
+ "app-aot-blobs",
"app-aot-assembly",
"app-aot-elf",
"vm-aot-assembly",
@@ -144,7 +146,8 @@
DEFINE_CB_OPTION(ProcessEnvironmentOption);
static bool IsSnapshottingForPrecompilation() {
- return (snapshot_kind == kAppAOTAssembly) || (snapshot_kind == kAppAOTElf) ||
+ return (snapshot_kind == kAppAOTBlobs) ||
+ (snapshot_kind == kAppAOTAssembly) || (snapshot_kind == kAppAOTElf) ||
(snapshot_kind == kVMAOTAssembly);
}
@@ -283,6 +286,34 @@
}
break;
}
+ case kAppAOTBlobs: {
+ if ((blobs_container_filename == NULL) &&
+ ((vm_snapshot_data_filename == NULL) ||
+ (vm_snapshot_instructions_filename == NULL) ||
+ (isolate_snapshot_data_filename == NULL) ||
+ (isolate_snapshot_instructions_filename == NULL))) {
+ Syslog::PrintErr(
+ "Building an AOT snapshot as blobs requires specifying output "
+ "file for --blobs_container_filename or "
+ "files for --vm_snapshot_data, --vm_snapshot_instructions, "
+ "--isolate_snapshot_data and --isolate_snapshot_instructions.\n\n");
+ return -1;
+ }
+ if ((blobs_container_filename != NULL) &&
+ ((vm_snapshot_data_filename != NULL) ||
+ (vm_snapshot_instructions_filename != NULL) ||
+ (isolate_snapshot_data_filename != NULL) ||
+ (isolate_snapshot_instructions_filename != NULL))) {
+ Syslog::PrintErr(
+ "Building an AOT snapshot as blobs requires specifying output "
+ "file for --blobs_container_filename or "
+ "files for --vm_snapshot_data, --vm_snapshot_instructions, "
+ "--isolate_snapshot_data and --isolate_snapshot_instructions"
+ " not both.\n\n");
+ return -1;
+ }
+ break;
+ }
case kAppAOTElf: {
if (elf_filename == NULL) {
Syslog::PrintErr(
@@ -638,6 +669,54 @@
" To avoid this, use --strip to remove it and "
"--save-debugging-info=<...> to save it to a separate file.\n");
}
+ } else if (snapshot_kind == kAppAOTBlobs) {
+ Syslog::PrintErr(
+ "WARNING: app-aot-blobs snapshots have been deprecated and support for "
+ "generating them will be removed soon. Please use the app-aot-elf or "
+ "app-aot-assembly snapshot kinds in conjunction with the portable ELF "
+ "loader from //runtime/bin:elf_loader if necessary. See "
+ "http://dartbug.com/38764 for more details.\n");
+
+ uint8_t* vm_snapshot_data_buffer = NULL;
+ intptr_t vm_snapshot_data_size = 0;
+ uint8_t* vm_snapshot_instructions_buffer = NULL;
+ intptr_t vm_snapshot_instructions_size = 0;
+ uint8_t* isolate_snapshot_data_buffer = NULL;
+ intptr_t isolate_snapshot_data_size = 0;
+ uint8_t* isolate_snapshot_instructions_buffer = NULL;
+ intptr_t isolate_snapshot_instructions_size = 0;
+ File* debug_file = nullptr;
+ if (debugging_info_filename != nullptr) {
+ debug_file = OpenFile(debugging_info_filename);
+ }
+ result = Dart_CreateAppAOTSnapshotAsBlobs(
+ &vm_snapshot_data_buffer, &vm_snapshot_data_size,
+ &vm_snapshot_instructions_buffer, &vm_snapshot_instructions_size,
+ &isolate_snapshot_data_buffer, &isolate_snapshot_data_size,
+ &isolate_snapshot_instructions_buffer,
+ &isolate_snapshot_instructions_size, StreamingWriteCallback,
+ debug_file);
+ if (debug_file != nullptr) debug_file->Release();
+ CHECK_RESULT(result);
+
+ if (blobs_container_filename != NULL) {
+ Snapshot::WriteAppSnapshot(
+ blobs_container_filename, vm_snapshot_data_buffer,
+ vm_snapshot_data_size, vm_snapshot_instructions_buffer,
+ vm_snapshot_instructions_size, isolate_snapshot_data_buffer,
+ isolate_snapshot_data_size, isolate_snapshot_instructions_buffer,
+ isolate_snapshot_instructions_size);
+ } else {
+ WriteFile(vm_snapshot_data_filename, vm_snapshot_data_buffer,
+ vm_snapshot_data_size);
+ WriteFile(vm_snapshot_instructions_filename,
+ vm_snapshot_instructions_buffer, vm_snapshot_instructions_size);
+ WriteFile(isolate_snapshot_data_filename, isolate_snapshot_data_buffer,
+ isolate_snapshot_data_size);
+ WriteFile(isolate_snapshot_instructions_filename,
+ isolate_snapshot_instructions_buffer,
+ isolate_snapshot_instructions_size);
+ }
} else {
UNREACHABLE();
}
@@ -747,6 +826,7 @@
CreateAndWriteAppJITSnapshot();
break;
case kAppAOTAssembly:
+ case kAppAOTBlobs:
case kAppAOTElf:
CreateAndWritePrecompiledSnapshot();
break;
diff --git a/runtime/bin/snapshot_utils.cc b/runtime/bin/snapshot_utils.cc
index 36f6293..bf9d270 100644
--- a/runtime/bin/snapshot_utils.cc
+++ b/runtime/bin/snapshot_utils.cc
@@ -509,6 +509,29 @@
#endif
}
+void Snapshot::GenerateAppAOTAsBlobs(const char* snapshot_filename) {
+ uint8_t* vm_data_buffer = NULL;
+ intptr_t vm_data_size = 0;
+ uint8_t* vm_instructions_buffer = NULL;
+ intptr_t vm_instructions_size = 0;
+ uint8_t* isolate_data_buffer = NULL;
+ intptr_t isolate_data_size = 0;
+ uint8_t* isolate_instructions_buffer = NULL;
+ intptr_t isolate_instructions_size = 0;
+ Dart_Handle result = Dart_CreateAppAOTSnapshotAsBlobs(
+ &vm_data_buffer, &vm_data_size, &vm_instructions_buffer,
+ &vm_instructions_size, &isolate_data_buffer, &isolate_data_size,
+ &isolate_instructions_buffer, &isolate_instructions_size,
+ /*callback=*/nullptr, /*debug_callback_info=*/nullptr);
+ if (Dart_IsError(result)) {
+ ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+ }
+ WriteAppSnapshot(snapshot_filename, vm_data_buffer, vm_data_size,
+ vm_instructions_buffer, vm_instructions_size,
+ isolate_data_buffer, isolate_data_size,
+ isolate_instructions_buffer, isolate_instructions_size);
+}
+
static void StreamingWriteCallback(void* callback_data,
const uint8_t* buffer,
intptr_t size) {
diff --git a/runtime/bin/snapshot_utils.h b/runtime/bin/snapshot_utils.h
index e84014c..b17875c 100644
--- a/runtime/bin/snapshot_utils.h
+++ b/runtime/bin/snapshot_utils.h
@@ -32,6 +32,7 @@
const char* script_name,
const char* package_config);
static void GenerateAppJIT(const char* snapshot_filename);
+ static void GenerateAppAOTAsBlobs(const char* snapshot_filename);
static void GenerateAppAOTAsAssembly(const char* snapshot_filename);
static AppSnapshot* TryReadAppendedAppSnapshotElf(const char* container_path);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 1679968..c68de7b 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3481,6 +3481,31 @@
void* callback_data);
/**
+ * Same as Dart_CreateAppAOTSnapshotAsAssembly, except all the pieces are
+ * provided directly as bytes that the embedder can load with mmap. The
+ * instructions pieces must be loaded with read and execute permissions; the
+ * other pieces may be loaded as read-only.
+ *
+ * This function has been DEPRECATED. Please use Dart_CreateAppAOTSnapshotAsELF
+ * or Dart_CreateAppAOTSnapshotAsAssembly instead. A portable ELF loader is
+ * available in the target //runtime/bin:elf_loader.
+ *
+ * If callback and debug_callback_data are provided, debug_callback_data will
+ * be used with the callback to provide separate debugging information.
+ */
+DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
+Dart_CreateAppAOTSnapshotAsBlobs(uint8_t** vm_snapshot_data_buffer,
+ intptr_t* vm_snapshot_data_size,
+ uint8_t** vm_snapshot_instructions_buffer,
+ intptr_t* vm_snapshot_instructions_size,
+ uint8_t** isolate_snapshot_data_buffer,
+ intptr_t* isolate_snapshot_data_size,
+ uint8_t** isolate_snapshot_instructions_buffer,
+ intptr_t* isolate_snapshot_instructions_size,
+ Dart_StreamingWriteCallback callback,
+ void* debug_callback_data);
+
+/**
* Sorts the class-ids in depth first traversal order of the inheritance
* tree. This is a costly operation, but it can make method dispatch
* more efficient and is done before writing snapshots.
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 490114e..0a40666 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -473,6 +473,14 @@
#if defined(DART_PRECOMPILED_RUNTIME)
code = function.CurrentCode();
+
+ // Blobs snapshots don't support BSS-relative relocations required by native
+ // callbacks (yet). Issue an error if the code has an unpatched relocation.
+ if (!code.VerifyBSSRelocations()) {
+ Exceptions::ThrowUnsupportedError(
+ "FFI callbacks are not yet supported in blobs snapshots. Please use "
+ "ELF or Assembly snapshots instead.");
+ }
#else
// We compile the callback immediately because we need to return a pointer to
// the entry-point. Native calls do not use patching like Dart calls, so we
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 665e212..601099c 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6241,6 +6241,78 @@
#endif
}
+DART_EXPORT Dart_Handle
+Dart_CreateAppAOTSnapshotAsBlobs(uint8_t** vm_snapshot_data_buffer,
+ intptr_t* vm_snapshot_data_size,
+ uint8_t** vm_snapshot_instructions_buffer,
+ intptr_t* vm_snapshot_instructions_size,
+ uint8_t** isolate_snapshot_data_buffer,
+ intptr_t* isolate_snapshot_data_size,
+ uint8_t** isolate_snapshot_instructions_buffer,
+ intptr_t* isolate_snapshot_instructions_size,
+ Dart_StreamingWriteCallback callback,
+ void* debug_callback_data) {
+#if defined(TARGET_ARCH_IA32)
+ return Api::NewError("AOT compilation is not supported on IA32.");
+#elif !defined(DART_PRECOMPILER)
+ return Api::NewError(
+ "This VM was built without support for AOT compilation.");
+#else
+ DARTSCOPE(Thread::Current());
+ API_TIMELINE_DURATION(T);
+ Isolate* I = T->isolate();
+ if (I->compilation_allowed()) {
+ return Api::NewError(
+ "Isolate is not precompiled. "
+ "Did you forget to call Dart_Precompile?");
+ }
+ CHECK_NULL(vm_snapshot_data_buffer);
+ CHECK_NULL(vm_snapshot_data_size);
+ CHECK_NULL(vm_snapshot_instructions_buffer);
+ CHECK_NULL(vm_snapshot_instructions_size);
+ CHECK_NULL(isolate_snapshot_data_buffer);
+ CHECK_NULL(isolate_snapshot_data_size);
+ CHECK_NULL(isolate_snapshot_instructions_buffer);
+ CHECK_NULL(isolate_snapshot_instructions_size);
+
+ TIMELINE_DURATION(T, Isolate, "WriteAppAOTSnapshot");
+
+ const bool generate_debug = debug_callback_data != nullptr;
+
+ StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
+ callback, debug_callback_data);
+
+ Elf* elf = nullptr;
+ Dwarf* dwarf = nullptr;
+ if (generate_debug) {
+ elf = new (Z) Elf(Z, &debug_stream);
+ dwarf = new (Z) Dwarf(Z, nullptr, elf);
+ }
+
+ BlobImageWriter vm_image_writer(T, vm_snapshot_instructions_buffer,
+ ApiReallocate, kInitialSize, dwarf);
+ BlobImageWriter isolate_image_writer(T, isolate_snapshot_instructions_buffer,
+ ApiReallocate, kInitialSize, dwarf);
+ FullSnapshotWriter writer(Snapshot::kFullAOT, vm_snapshot_data_buffer,
+ isolate_snapshot_data_buffer, ApiReallocate,
+ &vm_image_writer, &isolate_image_writer);
+
+ writer.WriteFullSnapshot();
+ *vm_snapshot_data_size = writer.VmIsolateSnapshotSize();
+ *vm_snapshot_instructions_size = vm_image_writer.InstructionsBlobSize();
+ *isolate_snapshot_data_size = writer.IsolateSnapshotSize();
+ *isolate_snapshot_instructions_size =
+ isolate_image_writer.InstructionsBlobSize();
+
+ if (generate_debug) {
+ dwarf->Write();
+ elf->Finalize();
+ }
+
+ return Api::Success();
+#endif
+}
+
#if (!defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME))
// Any flag that affects how we compile code might cause a problem when the
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index b8afa52..d1bd1bf 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -1028,8 +1028,8 @@
bss_base_(bss_base),
debug_dwarf_(debug_dwarf) {
#if defined(DART_PRECOMPILER)
- RELEASE_ASSERT(elf_ != nullptr &&
- (elf_dwarf_ == nullptr || elf_dwarf_->elf() == elf_));
+ RELEASE_ASSERT(elf_ == nullptr || elf_dwarf_ == nullptr ||
+ elf_dwarf_->elf() == elf_);
#else
RELEASE_ASSERT(elf_ == nullptr);
RELEASE_ASSERT(elf_dwarf_ == nullptr);
@@ -1048,9 +1048,10 @@
FLAG_precompiled_mode && FLAG_use_bare_instructions;
#ifdef DART_PRECOMPILER
- ASSERT(elf_ != nullptr);
intptr_t segment_base = 0;
- segment_base = elf_->NextMemoryOffset();
+ if (elf_ != nullptr) {
+ segment_base = elf_->NextMemoryOffset();
+ }
intptr_t debug_segment_base = 0;
if (debug_dwarf_ != nullptr) {
debug_segment_base = debug_dwarf_->elf()->NextMemoryOffset();
@@ -1063,7 +1064,8 @@
next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
instructions_blob_stream_.WriteTargetWord(image_size);
#if defined(DART_PRECOMPILER)
- instructions_blob_stream_.WriteTargetWord(bss_base_ - segment_base);
+ instructions_blob_stream_.WriteTargetWord(
+ elf_ != nullptr ? bss_base_ - segment_base : 0);
#else
instructions_blob_stream_.WriteTargetWord(0); // No relocations.
#endif
@@ -1210,7 +1212,7 @@
#endif
#if defined(DART_PRECOMPILER)
- if (elf_dwarf_ != nullptr) {
+ if (elf_ != nullptr && elf_dwarf_ != nullptr) {
const auto& code = *instructions_[i].code_;
auto const virtual_address = segment_base + payload_stream_start;
elf_dwarf_->AddCode(code, virtual_address);
@@ -1223,33 +1225,39 @@
debug_dwarf_->AddCode(code, virtual_address);
}
- const intptr_t current_stream_position =
- instructions_blob_stream_.Position();
+ // Don't patch the relocation if we're not generating ELF. The regular blobs
+ // format does not yet support these relocations. Use
+ // Code::VerifyBSSRelocations to check whether the relocations are patched
+ // or not after loading.
+ if (elf_ != nullptr) {
+ const intptr_t current_stream_position =
+ instructions_blob_stream_.Position();
- descriptors = data.code_->pc_descriptors();
+ descriptors = data.code_->pc_descriptors();
- PcDescriptors::Iterator iterator(
- descriptors, /*kind_mask=*/RawPcDescriptors::kBSSRelocation);
+ PcDescriptors::Iterator iterator(
+ descriptors, /*kind_mask=*/RawPcDescriptors::kBSSRelocation);
- while (iterator.MoveNext()) {
- const intptr_t reloc_offset = iterator.PcOffset();
+ while (iterator.MoveNext()) {
+ const intptr_t reloc_offset = iterator.PcOffset();
- // The instruction stream at the relocation position holds an offset
- // into BSS corresponding to the symbol being resolved. This addend is
- // factored into the relocation.
- const auto addend = *reinterpret_cast<compiler::target::word*>(
- insns.PayloadStart() + reloc_offset);
+ // The instruction stream at the relocation position holds an offset
+ // into BSS corresponding to the symbol being resolved. This addend is
+ // factored into the relocation.
+ const auto addend = *reinterpret_cast<compiler::target::word*>(
+ insns.PayloadStart() + reloc_offset);
- // Overwrite the relocation position in the instruction stream with the
- // (positive) offset of the start of the payload from the start of the
- // BSS segment plus the addend in the relocation.
- instructions_blob_stream_.SetPosition(payload_stream_start +
- reloc_offset);
+ // Overwrite the relocation position in the instruction stream with the
+ // (positive) offset of the start of the payload from the start of the
+ // BSS segment plus the addend in the relocation.
+ instructions_blob_stream_.SetPosition(payload_stream_start +
+ reloc_offset);
- const compiler::target::word offset =
- bss_base_ - (segment_base + payload_stream_start + reloc_offset) +
- addend;
- instructions_blob_stream_.WriteTargetWord(offset);
+ const compiler::target::word offset =
+ bss_base_ - (segment_base + payload_stream_start + reloc_offset) +
+ addend;
+ instructions_blob_stream_.WriteTargetWord(offset);
+ }
// Restore stream position after the relocation was patched.
instructions_blob_stream_.SetPosition(current_stream_position);
@@ -1273,10 +1281,12 @@
#ifdef DART_PRECOMPILER
const char* instructions_symbol =
vm ? "_kDartVmSnapshotInstructions" : "_kDartIsolateSnapshotInstructions";
- auto const segment_base2 =
- elf_->AddText(instructions_symbol, instructions_blob_stream_.buffer(),
- instructions_blob_stream_.bytes_written());
- ASSERT(segment_base == segment_base2);
+ if (elf_ != nullptr) {
+ auto const segment_base2 =
+ elf_->AddText(instructions_symbol, instructions_blob_stream_.buffer(),
+ instructions_blob_stream_.bytes_written());
+ ASSERT(segment_base == segment_base2);
+ }
if (debug_dwarf_ != nullptr) {
auto const debug_segment_base2 = debug_dwarf_->elf()->AddText(
instructions_symbol, instructions_blob_stream_.buffer(),
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index f7e931e..c28ef48 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -15880,6 +15880,24 @@
reader.DumpSourcePositions(relative_addresses ? 0 : PayloadStart());
}
+bool Code::VerifyBSSRelocations() const {
+ const auto& descriptors = PcDescriptors::Handle(pc_descriptors());
+ PcDescriptors::Iterator iterator(descriptors,
+ RawPcDescriptors::kBSSRelocation);
+ while (iterator.MoveNext()) {
+ const uword reloc = PayloadStart() + iterator.PcOffset();
+ const word target = *reinterpret_cast<word*>(reloc);
+ // The relocation is in its original unpatched form -- the addend
+ // representing the target symbol itself.
+ if (target >= 0 &&
+ target <
+ BSS::RelocationIndex(BSS::Relocation::NumRelocations) * kWordSize) {
+ return false;
+ }
+ }
+ return true;
+}
+
void Bytecode::Disassemble(DisassemblyFormatter* formatter) const {
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
#if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3d67731..8b8f9fa 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5815,6 +5815,9 @@
void Disassemble(DisassemblyFormatter* formatter = NULL) const;
+ // Returns true if all BSS relocations in the code have been patched.
+ bool VerifyBSSRelocations() const;
+
class Comments : public ZoneAllocated {
public:
static Comments& New(intptr_t count);
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index f327d2d..24f9e46 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -625,7 +625,7 @@
"dartk-android-(debug|product|release)-(arm|arm64)": {},
"dartkp-(linux|win|mac)-(debug|product|release)-(simarm|simarm64)": {
"options": {
- "use-elf": true
+ "use-blobs": true
}
},
"dartkp-linux-(debug|product|release)-simarm-crossword": {
@@ -636,7 +636,7 @@
"dartkp-(win|mac)-(debug|product|release)-simarm-crossword": {
"options": {
"builder-tag": "crossword",
- "use-elf": true
+ "use-blobs": true
}
},
"dartkp-win-(product|release)-x64": {
@@ -713,7 +713,7 @@
"dartkp-(linux|mac)-(debug|product|release)-simarm64-ast": {
"options": {
"builder-tag": "ast",
- "use-elf": true,
+ "use-blobs": true,
"gen-kernel-options": [
"--no-gen-bytecode"
]