mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:43:57 +00:00
[VM/Runtime] Report error when an AOT snapshot is used in spawnUri while
running in the JIT VM TEST=new test added Bug:54528 Change-Id: Ifa0176ee453e5af4e45bb0b74cf9ac9ba23fb93e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346060 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Siva Annamalai <asiva@google.com>
This commit is contained in:
parent
1e5480262c
commit
eabfad1158
|
@ -37,6 +37,13 @@ const char* DartUtils::original_working_directory = nullptr;
|
|||
dart::SimpleHashMap* DartUtils::environment_ = nullptr;
|
||||
|
||||
MagicNumberData appjit_magic_number = {8, {0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0}};
|
||||
MagicNumberData aotelf_magic_number = {4, {0x7F, 0x45, 0x4C, 0x46, 0x0}};
|
||||
MagicNumberData aotmacho32_magic_number = {4, {0xFE, 0xED, 0xFA, 0xCE}};
|
||||
MagicNumberData aotmacho64_magic_number = {4, {0xFE, 0xED, 0xFA, 0xCF}};
|
||||
MagicNumberData aotcoff_arm32_magic_number = {2, {0x01, 0xC0}};
|
||||
MagicNumberData aotcoff_arm64_magic_number = {2, {0xAA, 0x64}};
|
||||
MagicNumberData aotcoff_riscv32_magic_number = {2, {0x50, 0x32}};
|
||||
MagicNumberData aotcoff_riscv64_magic_number = {2, {0x50, 0x64}};
|
||||
MagicNumberData kernel_magic_number = {4, {0x90, 0xab, 0xcd, 0xef}};
|
||||
MagicNumberData kernel_list_magic_number = {
|
||||
7,
|
||||
|
@ -398,22 +405,23 @@ static bool CheckMagicNumber(const uint8_t* buffer,
|
|||
|
||||
DartUtils::MagicNumber DartUtils::SniffForMagicNumber(const char* filename) {
|
||||
MagicNumber magic_number = DartUtils::kUnknownMagicNumber;
|
||||
ASSERT(kMaxMagicNumberSize == appjit_magic_number.length);
|
||||
ASSERT(aotelf_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(aotmacho32_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(aotmacho64_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(aotcoff_arm32_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(aotcoff_arm64_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(aotcoff_riscv32_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(aotcoff_riscv64_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(kernel_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(kernel_list_magic_number.length <= appjit_magic_number.length);
|
||||
ASSERT(gzip_magic_number.length <= appjit_magic_number.length);
|
||||
if (File::GetType(nullptr, filename, true) == File::kIsFile) {
|
||||
File* file = File::Open(nullptr, filename, File::kRead);
|
||||
if (file != nullptr) {
|
||||
RefCntReleaseScope<File> rs(file);
|
||||
intptr_t max_magic_length = 0;
|
||||
max_magic_length =
|
||||
Utils::Maximum(max_magic_length, appjit_magic_number.length);
|
||||
max_magic_length =
|
||||
Utils::Maximum(max_magic_length, kernel_magic_number.length);
|
||||
max_magic_length =
|
||||
Utils::Maximum(max_magic_length, kernel_list_magic_number.length);
|
||||
max_magic_length =
|
||||
Utils::Maximum(max_magic_length, gzip_magic_number.length);
|
||||
ASSERT(max_magic_length <= 8);
|
||||
uint8_t header[8];
|
||||
if (file->ReadFully(&header, max_magic_length)) {
|
||||
uint8_t header[kMaxMagicNumberSize];
|
||||
if (file->ReadFully(&header, kMaxMagicNumberSize)) {
|
||||
magic_number = DartUtils::SniffForMagicNumber(header, sizeof(header));
|
||||
}
|
||||
}
|
||||
|
@ -443,6 +451,34 @@ DartUtils::MagicNumber DartUtils::SniffForMagicNumber(const uint8_t* buffer,
|
|||
return kGzipMagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotelf_magic_number)) {
|
||||
return kAotELFMagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotmacho32_magic_number)) {
|
||||
return kAotMachO32MagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotmacho64_magic_number)) {
|
||||
return kAotMachO64MagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotcoff_arm32_magic_number)) {
|
||||
return kAotCoffARM32MagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotcoff_arm64_magic_number)) {
|
||||
return kAotCoffARM64MagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotcoff_riscv32_magic_number)) {
|
||||
return kAotCoffRISCV32MagicNumber;
|
||||
}
|
||||
|
||||
if (CheckMagicNumber(buffer, buffer_length, aotcoff_riscv64_magic_number)) {
|
||||
return kAotCoffRISCV64MagicNumber;
|
||||
}
|
||||
|
||||
return kUnknownMagicNumber;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,8 +245,23 @@ class DartUtils {
|
|||
kKernelMagicNumber,
|
||||
kKernelListMagicNumber,
|
||||
kGzipMagicNumber,
|
||||
kAotELFMagicNumber,
|
||||
kAotMachO32MagicNumber,
|
||||
kAotMachO64MagicNumber,
|
||||
kAotCoffARM32MagicNumber,
|
||||
kAotCoffARM64MagicNumber,
|
||||
kAotCoffRISCV32MagicNumber,
|
||||
kAotCoffRISCV64MagicNumber,
|
||||
kUnknownMagicNumber
|
||||
};
|
||||
static constexpr int64_t kMaxMagicNumberSize = 8;
|
||||
|
||||
// Note: The check for AOT magic number must match up with the enum
|
||||
// order above.
|
||||
static bool IsAotMagicNumber(MagicNumber number) {
|
||||
return (number >= DartUtils::kAotELFMagicNumber) &&
|
||||
(number <= DartUtils::kAotCoffRISCV64MagicNumber);
|
||||
}
|
||||
|
||||
// Checks if the buffer is a script snapshot, kernel file, or gzip file.
|
||||
static MagicNumber SniffForMagicNumber(const char* filename);
|
||||
|
@ -629,6 +644,7 @@ struct MagicNumberData {
|
|||
};
|
||||
|
||||
extern MagicNumberData appjit_magic_number;
|
||||
extern MagicNumberData aotelf_magic_number;
|
||||
extern MagicNumberData kernel_magic_number;
|
||||
extern MagicNumberData kernel_list_magic_number;
|
||||
extern MagicNumberData gzip_magic_number;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "bin/file.h"
|
||||
#include "bin/lockers.h"
|
||||
#include "bin/platform.h"
|
||||
#include "bin/snapshot_utils.h"
|
||||
#include "bin/utils.h"
|
||||
#include "include/dart_tools_api.h"
|
||||
#include "platform/utils.h"
|
||||
|
@ -238,13 +239,14 @@ void DFE::CompileAndReadScript(const char* script_uri,
|
|||
}
|
||||
|
||||
void DFE::ReadScript(const char* script_uri,
|
||||
const AppSnapshot* app_snapshot,
|
||||
uint8_t** kernel_buffer,
|
||||
intptr_t* kernel_buffer_size,
|
||||
bool decode_uri,
|
||||
std::shared_ptr<uint8_t>* kernel_blob_ptr) {
|
||||
int64_t start = Dart_TimelineGetMicros();
|
||||
if (!TryReadKernelFile(script_uri, kernel_buffer, kernel_buffer_size,
|
||||
decode_uri, kernel_blob_ptr)) {
|
||||
if (!TryReadKernelFile(script_uri, app_snapshot, kernel_buffer,
|
||||
kernel_buffer_size, decode_uri, kernel_blob_ptr)) {
|
||||
return;
|
||||
}
|
||||
if (!Dart_IsKernel(*kernel_buffer, *kernel_buffer_size)) {
|
||||
|
@ -435,6 +437,7 @@ static bool TryReadKernelListBuffer(const char* script_uri,
|
|||
}
|
||||
|
||||
bool DFE::TryReadKernelFile(const char* script_uri,
|
||||
const AppSnapshot* app_snapshot,
|
||||
uint8_t** kernel_ir,
|
||||
intptr_t* kernel_ir_size,
|
||||
bool decode_uri,
|
||||
|
@ -451,19 +454,31 @@ bool DFE::TryReadKernelFile(const char* script_uri,
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* buffer;
|
||||
if (!TryReadFile(script_uri, &buffer, kernel_ir_size, decode_uri)) {
|
||||
return false;
|
||||
if (app_snapshot == nullptr || app_snapshot->IsKernel() ||
|
||||
app_snapshot->IsKernelList()) {
|
||||
uint8_t* buffer;
|
||||
if (!TryReadFile(script_uri, &buffer, kernel_ir_size, decode_uri)) {
|
||||
return false;
|
||||
}
|
||||
auto magic_number = DartUtils::kUnknownMagicNumber;
|
||||
if (app_snapshot == nullptr) {
|
||||
magic_number = DartUtils::SniffForMagicNumber(buffer, *kernel_ir_size);
|
||||
} else if (app_snapshot->IsKernel()) {
|
||||
magic_number = DartUtils::kKernelMagicNumber;
|
||||
ASSERT(DartUtils::SniffForMagicNumber(buffer, *kernel_ir_size) ==
|
||||
DartUtils::kKernelMagicNumber);
|
||||
} else {
|
||||
magic_number = DartUtils::kKernelListMagicNumber;
|
||||
ASSERT(DartUtils::SniffForMagicNumber(buffer, *kernel_ir_size) ==
|
||||
DartUtils::kKernelListMagicNumber);
|
||||
}
|
||||
if (magic_number == DartUtils::kKernelListMagicNumber) {
|
||||
return TryReadKernelListBuffer(script_uri, buffer, *kernel_ir_size,
|
||||
kernel_ir, kernel_ir_size);
|
||||
}
|
||||
return TryReadSimpleKernelBuffer(buffer, kernel_ir, kernel_ir_size);
|
||||
}
|
||||
|
||||
DartUtils::MagicNumber magic_number =
|
||||
DartUtils::SniffForMagicNumber(buffer, *kernel_ir_size);
|
||||
if (magic_number == DartUtils::kKernelListMagicNumber) {
|
||||
return TryReadKernelListBuffer(script_uri, buffer, *kernel_ir_size,
|
||||
kernel_ir, kernel_ir_size);
|
||||
}
|
||||
return TryReadSimpleKernelBuffer(buffer, kernel_ir, kernel_ir_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* DFE::RegisterKernelBlob(const uint8_t* kernel_buffer,
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
class AppSnapshot; // Forward declaration.
|
||||
|
||||
class DFE {
|
||||
public:
|
||||
DFE();
|
||||
|
@ -100,6 +102,7 @@ class DFE {
|
|||
// to a shared pointer which owns the kernel buffer.
|
||||
// Otherwise, the caller is responsible for free()ing 'kernel_buffer'.
|
||||
void ReadScript(const char* script_uri,
|
||||
const AppSnapshot* app_snapshot,
|
||||
uint8_t** kernel_buffer,
|
||||
intptr_t* kernel_buffer_size,
|
||||
bool decode_uri = true,
|
||||
|
@ -117,6 +120,7 @@ class DFE {
|
|||
// Otherwise, the caller is responsible for free()ing 'kernel_buffer'
|
||||
// if `true` was returned.
|
||||
bool TryReadKernelFile(const char* script_uri,
|
||||
const AppSnapshot* app_snapshot,
|
||||
uint8_t** kernel_buffer,
|
||||
intptr_t* kernel_buffer_size,
|
||||
bool decode_uri = true,
|
||||
|
|
|
@ -93,7 +93,7 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
|
|||
if (tag == Dart_kKernelTag) {
|
||||
uint8_t* kernel_buffer = nullptr;
|
||||
intptr_t kernel_buffer_size = 0;
|
||||
if (!dfe.TryReadKernelFile(url_string, &kernel_buffer,
|
||||
if (!dfe.TryReadKernelFile(url_string, nullptr, &kernel_buffer,
|
||||
&kernel_buffer_size)) {
|
||||
return DartUtils::NewError("'%s' is not a kernel file", url_string);
|
||||
}
|
||||
|
|
|
@ -430,11 +430,12 @@ static Dart_Isolate CreateAndSetupKernelIsolate(const char* script_uri,
|
|||
IsolateData* isolate_data = nullptr;
|
||||
bool isolate_run_app_snapshot = false;
|
||||
AppSnapshot* app_snapshot = nullptr;
|
||||
// Kernel isolate uses an app snapshot or uses the dill file.
|
||||
// Kernel isolate uses an app JIT snapshot or uses the dill file.
|
||||
if ((kernel_snapshot_uri != nullptr) &&
|
||||
(app_snapshot = Snapshot::TryReadAppSnapshot(
|
||||
kernel_snapshot_uri, /*force_load_elf_from_memory=*/false,
|
||||
/*decode_uri=*/false)) != nullptr) {
|
||||
((app_snapshot = Snapshot::TryReadAppSnapshot(
|
||||
kernel_snapshot_uri, /*force_load_elf_from_memory=*/false,
|
||||
/*decode_uri=*/false)) != nullptr) &&
|
||||
app_snapshot->IsJIT()) {
|
||||
const uint8_t* isolate_snapshot_data = nullptr;
|
||||
const uint8_t* isolate_snapshot_instructions = nullptr;
|
||||
const uint8_t* ignore_vm_snapshot_data;
|
||||
|
@ -611,9 +612,11 @@ static Dart_Isolate CreateAndSetupDartDevIsolate(const char* script_uri,
|
|||
IsolateData* isolate_data = nullptr;
|
||||
AppSnapshot* app_snapshot = nullptr;
|
||||
bool isolate_run_app_snapshot = true;
|
||||
if ((app_snapshot = Snapshot::TryReadAppSnapshot(
|
||||
dartdev_path.get(), /*force_load_elf_from_memory=*/false,
|
||||
/*decode_uri=*/false)) != nullptr) {
|
||||
// dartdev isolate uses an app JIT snapshot or uses the dill file.
|
||||
if (((app_snapshot = Snapshot::TryReadAppSnapshot(
|
||||
dartdev_path.get(), /*force_load_elf_from_memory=*/false,
|
||||
/*decode_uri=*/false)) != nullptr) &&
|
||||
app_snapshot->IsJIT()) {
|
||||
const uint8_t* isolate_snapshot_data = nullptr;
|
||||
const uint8_t* isolate_snapshot_instructions = nullptr;
|
||||
const uint8_t* ignore_vm_snapshot_data;
|
||||
|
@ -647,7 +650,7 @@ static Dart_Isolate CreateAndSetupDartDevIsolate(const char* script_uri,
|
|||
isolate_run_app_snapshot);
|
||||
uint8_t* application_kernel_buffer = nullptr;
|
||||
intptr_t application_kernel_buffer_size = 0;
|
||||
dfe.ReadScript(dartdev_path.get(), &application_kernel_buffer,
|
||||
dfe.ReadScript(dartdev_path.get(), nullptr, &application_kernel_buffer,
|
||||
&application_kernel_buffer_size, /*decode_uri=*/false);
|
||||
isolate_group_data->SetKernelBufferNewlyOwned(
|
||||
application_kernel_buffer, application_kernel_buffer_size);
|
||||
|
@ -702,10 +705,11 @@ static Dart_Isolate CreateIsolateGroupAndSetupHelper(
|
|||
const bool kForceLoadElfFromMemory = false;
|
||||
app_snapshot =
|
||||
Snapshot::TryReadAppSnapshot(script_uri, kForceLoadElfFromMemory);
|
||||
if (app_snapshot == nullptr) {
|
||||
*error = Utils::StrDup(
|
||||
"The uri provided to `Isolate.spawnUri()` does not "
|
||||
"contain a valid AOT snapshot.");
|
||||
if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
|
||||
*error = Utils::SCreate(
|
||||
"The uri(%s) provided to `Isolate.spawnUri()` does not "
|
||||
"contain a valid AOT snapshot.",
|
||||
script_uri);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -735,7 +739,14 @@ static Dart_Isolate CreateIsolateGroupAndSetupHelper(
|
|||
isolate_snapshot_instructions = app_isolate_snapshot_instructions;
|
||||
} else if (!is_main_isolate) {
|
||||
app_snapshot = Snapshot::TryReadAppSnapshot(script_uri);
|
||||
if (app_snapshot != nullptr) {
|
||||
if (app_snapshot != nullptr && app_snapshot->IsJITorAOT()) {
|
||||
if (app_snapshot->IsAOT()) {
|
||||
*error = Utils::SCreate(
|
||||
"The uri(%s) provided to `Isolate.spawnUri()` is an "
|
||||
"AOT snapshot and the JIT VM cannot spawn an isolate using it.",
|
||||
script_uri);
|
||||
return nullptr;
|
||||
}
|
||||
isolate_run_app_snapshot = true;
|
||||
const uint8_t* ignore_vm_snapshot_data;
|
||||
const uint8_t* ignore_vm_snapshot_instructions;
|
||||
|
@ -754,8 +765,9 @@ static Dart_Isolate CreateIsolateGroupAndSetupHelper(
|
|||
}
|
||||
|
||||
if (kernel_buffer == nullptr && !isolate_run_app_snapshot) {
|
||||
dfe.ReadScript(script_uri, &kernel_buffer, &kernel_buffer_size,
|
||||
/*decode_uri=*/true, &kernel_buffer_ptr);
|
||||
dfe.ReadScript(script_uri, app_snapshot, &kernel_buffer,
|
||||
&kernel_buffer_size, /*decode_uri=*/true,
|
||||
&kernel_buffer_ptr);
|
||||
}
|
||||
PathSanitizer script_uri_sanitizer(script_uri);
|
||||
PathSanitizer packages_config_sanitizer(packages_config);
|
||||
|
@ -1271,7 +1283,13 @@ void main(int argc, char** argv) {
|
|||
app_snapshot =
|
||||
Snapshot::TryReadAppSnapshot(script_name, force_load_elf_from_memory);
|
||||
}
|
||||
if (app_snapshot != nullptr) {
|
||||
if (app_snapshot != nullptr && app_snapshot->IsJITorAOT()) {
|
||||
if (app_snapshot->IsAOT() && !Dart_IsPrecompiledRuntime()) {
|
||||
Syslog::PrintErr(
|
||||
"%s is an AOT snapshot and should be run with 'dartaotruntime'\n",
|
||||
script_name);
|
||||
Platform::Exit(kErrorExitCode);
|
||||
}
|
||||
vm_run_app_snapshot = true;
|
||||
app_snapshot->SetBuffers(&vm_snapshot_data, &vm_snapshot_instructions,
|
||||
&app_isolate_snapshot_data,
|
||||
|
@ -1331,7 +1349,7 @@ void main(int argc, char** argv) {
|
|||
if (script_name != nullptr) {
|
||||
uint8_t* application_kernel_buffer = nullptr;
|
||||
intptr_t application_kernel_buffer_size = 0;
|
||||
dfe.ReadScript(script_name, &application_kernel_buffer,
|
||||
dfe.ReadScript(script_name, app_snapshot, &application_kernel_buffer,
|
||||
&application_kernel_buffer_size);
|
||||
if (application_kernel_buffer != nullptr) {
|
||||
// Since we loaded the script anyway, save it.
|
||||
|
@ -1415,21 +1433,12 @@ void main(int argc, char** argv) {
|
|||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
if (should_run_user_program) {
|
||||
if (!Dart_IsPrecompiledRuntime() && Snapshot::IsAOTSnapshot(script_name)) {
|
||||
Syslog::PrintErr(
|
||||
"%s is an AOT snapshot and should be run with 'dartaotruntime'\n",
|
||||
script_name);
|
||||
Platform::Exit(kErrorExitCode);
|
||||
if (Options::gen_snapshot_kind() == kKernel) {
|
||||
CompileAndSaveKernel(script_name, package_config_override, &dart_options);
|
||||
} else {
|
||||
if (Options::gen_snapshot_kind() == kKernel) {
|
||||
CompileAndSaveKernel(script_name, package_config_override,
|
||||
&dart_options);
|
||||
|
||||
} else {
|
||||
// Run the main isolate until we aren't told to restart.
|
||||
RunMainIsolate(script_name, package_config_override,
|
||||
force_no_sound_null_safety, &dart_options);
|
||||
}
|
||||
// Run the main isolate until we aren't told to restart.
|
||||
RunMainIsolate(script_name, package_config_override,
|
||||
force_no_sound_null_safety, &dart_options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,18 +26,37 @@
|
|||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
static constexpr int64_t kAppSnapshotHeaderSize = 5 * kInt64Size;
|
||||
static constexpr int64_t kAppSnapshotHeaderSize = 4 * kInt64Size;
|
||||
static constexpr int64_t kAppSnapshotPageSize = 16 * KB;
|
||||
|
||||
static const char kMachOAppSnapshotNoteName[] DART_UNUSED = "__dart_app_snap";
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
class DummySnapshot : public AppSnapshot {
|
||||
public:
|
||||
explicit DummySnapshot(DartUtils::MagicNumber num) : AppSnapshot(num) {}
|
||||
|
||||
~DummySnapshot() {}
|
||||
|
||||
void SetBuffers(const uint8_t** vm_data_buffer,
|
||||
const uint8_t** vm_instructions_buffer,
|
||||
const uint8_t** isolate_data_buffer,
|
||||
const uint8_t** isolate_instructions_buffer) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
class MappedAppSnapshot : public AppSnapshot {
|
||||
public:
|
||||
MappedAppSnapshot(MappedMemory* vm_snapshot_data,
|
||||
MappedMemory* vm_snapshot_instructions,
|
||||
MappedMemory* isolate_snapshot_data,
|
||||
MappedMemory* isolate_snapshot_instructions)
|
||||
: vm_data_mapping_(vm_snapshot_data),
|
||||
: AppSnapshot(DartUtils::kAppJITMagicNumber),
|
||||
vm_data_mapping_(vm_snapshot_data),
|
||||
vm_instructions_mapping_(vm_snapshot_instructions),
|
||||
isolate_data_mapping_(isolate_snapshot_data),
|
||||
isolate_instructions_mapping_(isolate_snapshot_instructions) {}
|
||||
|
@ -84,30 +103,24 @@ static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int64_t header[5];
|
||||
int64_t header[4];
|
||||
ASSERT(sizeof(header) == kAppSnapshotHeaderSize);
|
||||
if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
ASSERT(sizeof(header[0]) == appjit_magic_number.length);
|
||||
if (memcmp(&header[0], appjit_magic_number.bytes,
|
||||
appjit_magic_number.length) != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int64_t vm_data_size = header[1];
|
||||
int64_t vm_data_size = header[0];
|
||||
int64_t vm_data_position =
|
||||
Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
|
||||
int64_t vm_instructions_size = header[2];
|
||||
int64_t vm_instructions_size = header[1];
|
||||
int64_t vm_instructions_position = vm_data_position + vm_data_size;
|
||||
if (vm_instructions_size != 0) {
|
||||
vm_instructions_position =
|
||||
Utils::RoundUp(vm_instructions_position, kAppSnapshotPageSize);
|
||||
}
|
||||
int64_t isolate_data_size = header[3];
|
||||
int64_t isolate_data_size = header[2];
|
||||
int64_t isolate_data_position = Utils::RoundUp(
|
||||
vm_instructions_position + vm_instructions_size, kAppSnapshotPageSize);
|
||||
int64_t isolate_instructions_size = header[4];
|
||||
int64_t isolate_instructions_size = header[3];
|
||||
int64_t isolate_instructions_position =
|
||||
isolate_data_position + isolate_data_size;
|
||||
if (isolate_instructions_size != 0) {
|
||||
|
@ -152,17 +165,10 @@ static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name,
|
|||
}
|
||||
}
|
||||
|
||||
return new MappedAppSnapshot(vm_data_mapping, vm_instr_mapping,
|
||||
isolate_data_mapping, isolate_instr_mapping);
|
||||
}
|
||||
|
||||
static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name) {
|
||||
File* file = File::Open(nullptr, script_name, File::kRead);
|
||||
if (file == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
RefCntReleaseScope<File> rs(file);
|
||||
return TryReadAppSnapshotBlobs(script_name, file);
|
||||
auto app_snapshot =
|
||||
new MappedAppSnapshot(vm_data_mapping, vm_instr_mapping,
|
||||
isolate_data_mapping, isolate_instr_mapping);
|
||||
return app_snapshot;
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
@ -173,7 +179,8 @@ class ElfAppSnapshot : public AppSnapshot {
|
|||
const uint8_t* vm_snapshot_instructions,
|
||||
const uint8_t* isolate_snapshot_data,
|
||||
const uint8_t* isolate_snapshot_instructions)
|
||||
: elf_(elf),
|
||||
: AppSnapshot{DartUtils::kAotELFMagicNumber},
|
||||
elf_(elf),
|
||||
vm_snapshot_data_(vm_snapshot_data),
|
||||
vm_snapshot_instructions_(vm_snapshot_instructions),
|
||||
isolate_snapshot_data_(isolate_snapshot_data),
|
||||
|
@ -432,7 +439,8 @@ class DylibAppSnapshot : public AppSnapshot {
|
|||
const uint8_t* vm_snapshot_instructions,
|
||||
const uint8_t* isolate_snapshot_data,
|
||||
const uint8_t* isolate_snapshot_instructions)
|
||||
: library_(library),
|
||||
: AppSnapshot(DartUtils::kAotELFMagicNumber),
|
||||
library_(library),
|
||||
vm_snapshot_data_(vm_snapshot_data),
|
||||
vm_snapshot_instructions_(vm_snapshot_instructions),
|
||||
isolate_snapshot_data_(isolate_snapshot_data),
|
||||
|
@ -597,11 +605,31 @@ AppSnapshot* Snapshot::TryReadAppSnapshot(const char* script_uri,
|
|||
// anyway if it was).
|
||||
return nullptr;
|
||||
}
|
||||
AppSnapshot* snapshot = TryReadAppSnapshotBlobs(script_name);
|
||||
if (snapshot != nullptr) {
|
||||
return snapshot;
|
||||
File* file = File::Open(nullptr, script_name, File::kRead);
|
||||
if (file == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
RefCntReleaseScope<File> rs(file);
|
||||
if ((file->Length() - file->Position()) < DartUtils::kMaxMagicNumberSize) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t header[DartUtils::kMaxMagicNumberSize];
|
||||
ASSERT(sizeof(header) == DartUtils::kMaxMagicNumberSize);
|
||||
if (!file->ReadFully(&header, DartUtils::kMaxMagicNumberSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
DartUtils::MagicNumber magic_number =
|
||||
DartUtils::SniffForMagicNumber(header, sizeof(header));
|
||||
if (magic_number == DartUtils::kAppJITMagicNumber) {
|
||||
// Return the JIT snapshot.
|
||||
return TryReadAppSnapshotBlobs(script_name, file);
|
||||
}
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
if (!DartUtils::IsAotMagicNumber(magic_number)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// For testing AOT with the standalone embedder, we also support loading
|
||||
// from a dynamic library to simulate what happens on iOS.
|
||||
|
||||
|
@ -613,16 +641,21 @@ AppSnapshot* Snapshot::TryReadAppSnapshot(const char* script_uri,
|
|||
script_name = absolute_path.get();
|
||||
#endif
|
||||
|
||||
AppSnapshot* snapshot = nullptr;
|
||||
if (!force_load_elf_from_memory) {
|
||||
snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
|
||||
if (snapshot != nullptr) {
|
||||
return snapshot;
|
||||
}
|
||||
}
|
||||
|
||||
return TryReadAppSnapshotElf(script_name, /*file_offset=*/0,
|
||||
force_load_elf_from_memory);
|
||||
#else
|
||||
// We create a dummy snapshot object just to remember the type which
|
||||
// has already been identified by sniffing the magic number.
|
||||
return new DummySnapshot(magic_number);
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -667,7 +700,8 @@ void Snapshot::WriteAppSnapshot(const char* filename,
|
|||
WriteInt64(file, vm_instructions_size);
|
||||
WriteInt64(file, isolate_data_size);
|
||||
WriteInt64(file, isolate_instructions_size);
|
||||
ASSERT(file->Position() == kAppSnapshotHeaderSize);
|
||||
ASSERT(file->Position() ==
|
||||
(kAppSnapshotHeaderSize + DartUtils::kMaxMagicNumberSize));
|
||||
|
||||
file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
|
||||
if (LOG_SECTION_BOUNDARIES) {
|
||||
|
@ -720,7 +754,7 @@ void Snapshot::GenerateKernel(const char* snapshot_filename,
|
|||
|
||||
uint8_t* kernel_buffer = nullptr;
|
||||
intptr_t kernel_buffer_size = 0;
|
||||
dfe.ReadScript(script_name, &kernel_buffer, &kernel_buffer_size);
|
||||
dfe.ReadScript(script_name, nullptr, &kernel_buffer, &kernel_buffer_size);
|
||||
if (kernel_buffer != nullptr) {
|
||||
WriteSnapshotFile(snapshot_filename, kernel_buffer, kernel_buffer_size);
|
||||
free(kernel_buffer);
|
||||
|
@ -795,24 +829,5 @@ void Snapshot::GenerateAppAOTAsAssembly(const char* snapshot_filename) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Snapshot::IsAOTSnapshot(const char* snapshot_filename) {
|
||||
// Header is simply "ELF" prefixed with the DEL character.
|
||||
const char elf_header[] = {0x7F, 0x45, 0x4C, 0x46, 0x0};
|
||||
const int64_t elf_header_len = strlen(elf_header);
|
||||
File* file = File::Open(nullptr, snapshot_filename, File::kRead);
|
||||
if (file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (file->Length() < elf_header_len) {
|
||||
file->Release();
|
||||
return false;
|
||||
}
|
||||
auto buf = std::unique_ptr<char[]>(new char[elf_header_len]);
|
||||
bool success = file->ReadFully(buf.get(), elf_header_len);
|
||||
file->Release();
|
||||
ASSERT(success);
|
||||
return (strncmp(elf_header, buf.get(), elf_header_len) == 0);
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef RUNTIME_BIN_SNAPSHOT_UTILS_H_
|
||||
#define RUNTIME_BIN_SNAPSHOT_UTILS_H_
|
||||
|
||||
#include "bin/dartutils.h"
|
||||
#include "platform/globals.h"
|
||||
|
||||
namespace dart {
|
||||
|
@ -19,10 +20,21 @@ class AppSnapshot {
|
|||
const uint8_t** isolate_data_buffer,
|
||||
const uint8_t** isolate_instructions_buffer) = 0;
|
||||
|
||||
bool IsJIT() const { return magic_number_ == DartUtils::kAppJITMagicNumber; }
|
||||
bool IsAOT() const { return DartUtils::IsAotMagicNumber(magic_number_); }
|
||||
bool IsJITorAOT() const { return IsJIT() || IsAOT(); }
|
||||
bool IsKernel() const {
|
||||
return magic_number_ == DartUtils::kKernelMagicNumber;
|
||||
}
|
||||
bool IsKernelList() const {
|
||||
return magic_number_ == DartUtils::kKernelListMagicNumber;
|
||||
}
|
||||
|
||||
protected:
|
||||
AppSnapshot() {}
|
||||
explicit AppSnapshot(DartUtils::MagicNumber num) : magic_number_(num) {}
|
||||
|
||||
private:
|
||||
DartUtils::MagicNumber magic_number_;
|
||||
DISALLOW_COPY_AND_ASSIGN(AppSnapshot);
|
||||
};
|
||||
|
||||
|
@ -34,10 +46,6 @@ class Snapshot {
|
|||
static void GenerateAppJIT(const char* snapshot_filename);
|
||||
static void GenerateAppAOTAsAssembly(const char* snapshot_filename);
|
||||
|
||||
// Returns true if snapshot_filename points to an AOT snapshot (aka,
|
||||
// an ELF binary). May report false negatives.
|
||||
static bool IsAOTSnapshot(const char* snapshot_filename);
|
||||
|
||||
#if defined(DART_TARGET_OS_MACOS)
|
||||
static bool IsMachOFormattedBinary(const char* container_path);
|
||||
#endif
|
||||
|
|
7
runtime/tests/vm/dart/isolates/func.dart
Normal file
7
runtime/tests/vm/dart/isolates/func.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
|
||||
// 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.
|
||||
/* file: func.dart */
|
||||
void main() {
|
||||
print('func.dart');
|
||||
}
|
63
runtime/tests/vm/dart/isolates/regress_54528_test.dart
Normal file
63
runtime/tests/vm/dart/isolates/regress_54528_test.dart
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
|
||||
// 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.
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../use_flag_test_helper.dart';
|
||||
|
||||
void main() async {
|
||||
var result = 1;
|
||||
final d = Directory.systemTemp.createTempSync('aot_tmp');
|
||||
try {
|
||||
// This test is checking if we get an error when a spawnURI is
|
||||
// done using an AOT snapshot in a JIT VM and hence is skipped
|
||||
// for AOT runs.
|
||||
if (isAOTRuntime) return;
|
||||
|
||||
if (Platform.isAndroid || Platform.isIOS) {
|
||||
return; // SDK tree not available on the test device.
|
||||
}
|
||||
|
||||
// These are the tools we need to be available to run on a given platform:
|
||||
if (!File(platformDill).existsSync()) {
|
||||
throw "Cannot run test as $platformDill does not exist";
|
||||
}
|
||||
|
||||
// Generate an AOT snapshot.
|
||||
final spawnTest =
|
||||
path.join(sdkDir, 'runtime/tests/vm/dart/isolates/func.dart');
|
||||
Expect.isTrue(File(spawnTest).existsSync(), "Can't locate $spawnTest");
|
||||
final kernelOutput = File.fromUri(d.uri.resolve('func.dill')).path;
|
||||
final aotOutput = File.fromUri(d.uri.resolve('func.aot')).path;
|
||||
|
||||
// Compile source to kernel.
|
||||
var result = Process.runSync(genKernel, <String>[
|
||||
'--aot',
|
||||
'--platform=$platformDill',
|
||||
'-o',
|
||||
kernelOutput,
|
||||
spawnTest,
|
||||
]);
|
||||
Expect.equals(result.exitCode, 0);
|
||||
result = Process.runSync(genSnapshot, <String>[
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=$aotOutput',
|
||||
kernelOutput,
|
||||
]);
|
||||
Expect.equals(result.exitCode, 0);
|
||||
|
||||
// Now try spawning an isolate using that AOT file that was just generated.
|
||||
final isolate = await Isolate.spawnUri(Uri.parse(aotOutput), [], null);
|
||||
} catch (e) {
|
||||
Expect.contains("func.aot", e.toString());
|
||||
result = 0;
|
||||
} finally {
|
||||
d.deleteSync(recursive: true);
|
||||
}
|
||||
Expect.equals(result, 0);
|
||||
}
|
|
@ -114,8 +114,9 @@ main(List<String> args) async {
|
|||
path.join(dir, 'does_not_exist.dart.dill.so'),
|
||||
]);
|
||||
Expect.notEquals(0, result3.exitCode);
|
||||
Expect.contains('The uri', result3.stderr);
|
||||
Expect.contains(
|
||||
'The uri provided to `Isolate.spawnUri()` does not contain a valid AOT '
|
||||
'provided to `Isolate.spawnUri()` does not contain a valid AOT '
|
||||
'snapshot',
|
||||
result3.stderr);
|
||||
});
|
||||
|
|
|
@ -197,6 +197,7 @@ cc/Profiler_TypedArrayAllocation: SkipByDesign
|
|||
cc/Service_Profile: SkipByDesign
|
||||
dart/gc/splay_c_finalizer_test: SkipByDesign # No FFI on simulators
|
||||
dart/isolates/dart_api_create_lightweight_isolate_test: SkipByDesign # https://dartbug.com/37299 Test uses dart:ffi which is not supported on simulators.
|
||||
dart/isolates/regress_54528_test: SkipByDesign # Invokes gen_kernel/gen_snapshot
|
||||
dart/isolates/thread_pool_test: SkipByDesign # https://dartbug.com/37299 Test uses dart:ffi which is not supported on simulators.
|
||||
dart/reachability_test: SkipByDesign # Test takes too long on the simulator
|
||||
dart/regress_41971_test: SkipByDesign # https://dartbug.com/37299 dart:ffi is not supported on simulator
|
||||
|
|
Loading…
Reference in a new issue