mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:41:41 +00:00
Add a new API function to sniff a snapshot to determine if the
snapshot is a Dart2 snapshot or a Dart1 snapshot. This will be used by the flutter engine to initialize itself correctly based on the snapshot provided. Change-Id: I06adaac74b350f96aa6ebb55887e4a81f09fbd14 Reviewed-on: https://dart-review.googlesource.com/41082 Commit-Queue: Siva Annamalai <asiva@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
4436877ab2
commit
9884447cc5
|
@ -1029,6 +1029,18 @@ DART_EXPORT Dart_Handle
|
|||
Dart_CreateScriptSnapshot(uint8_t** script_snapshot_buffer,
|
||||
intptr_t* script_snapshot_size);
|
||||
|
||||
/**
|
||||
* Returns true if snapshot_buffer contains a Dart2 snapshot.
|
||||
*
|
||||
* \param snapshot_buffer Pointer to a buffer that contains the snapshot
|
||||
* that needs to be checked.
|
||||
* \param snapshot_size Size of the buffer.
|
||||
*
|
||||
* \returns true if the snapshot is a Dart2 snapshot, false otherwise.
|
||||
*/
|
||||
DART_EXPORT bool Dart_IsDart2Snapshot(uint8_t* snapshot_buffer,
|
||||
intptr_t snapshot_size);
|
||||
|
||||
/**
|
||||
* Schedules an interrupt for the specified isolate.
|
||||
*
|
||||
|
|
|
@ -4846,14 +4846,14 @@ RawObject* Serializer::ParentOf(const Object& object) {
|
|||
}
|
||||
#endif // SNAPSHOT_BACKTRACE
|
||||
|
||||
void Serializer::WriteVersionAndFeatures() {
|
||||
void Serializer::WriteVersionAndFeatures(bool is_vm_snapshot) {
|
||||
const char* expected_version = Version::SnapshotString();
|
||||
ASSERT(expected_version != NULL);
|
||||
const intptr_t version_len = strlen(expected_version);
|
||||
WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
|
||||
|
||||
const char* expected_features =
|
||||
Dart::FeaturesString(Isolate::Current(), kind_);
|
||||
Dart::FeaturesString(Isolate::Current(), is_vm_snapshot, kind_);
|
||||
ASSERT(expected_features != NULL);
|
||||
const intptr_t features_len = strlen(expected_features);
|
||||
WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
|
||||
|
@ -5303,7 +5303,8 @@ RawApiError* Deserializer::VerifyVersionAndFeatures(Isolate* isolate) {
|
|||
}
|
||||
Advance(version_len);
|
||||
|
||||
const char* expected_features = Dart::FeaturesString(isolate, kind_);
|
||||
const char* expected_features =
|
||||
Dart::FeaturesString(isolate, (isolate == NULL), kind_);
|
||||
ASSERT(expected_features != NULL);
|
||||
const intptr_t expected_len = strlen(expected_features);
|
||||
|
||||
|
@ -5717,7 +5718,7 @@ intptr_t FullSnapshotWriter::WriteVMSnapshot() {
|
|||
kInitialSize, vm_image_writer_);
|
||||
|
||||
serializer.ReserveHeader();
|
||||
serializer.WriteVersionAndFeatures();
|
||||
serializer.WriteVersionAndFeatures(true);
|
||||
// VM snapshot roots are:
|
||||
// - the symbol table
|
||||
// - all the token streams
|
||||
|
@ -5749,7 +5750,7 @@ void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
|
|||
ASSERT(object_store != NULL);
|
||||
|
||||
serializer.ReserveHeader();
|
||||
serializer.WriteVersionAndFeatures();
|
||||
serializer.WriteVersionAndFeatures(false);
|
||||
// Isolate snapshot roots are:
|
||||
// - the object store
|
||||
serializer.WriteIsolateSnapshot(num_base_objects, object_store);
|
||||
|
|
|
@ -195,7 +195,7 @@ class Serializer : public StackResource {
|
|||
data[Snapshot::kSnapshotFlagIndex] = kind;
|
||||
}
|
||||
|
||||
void WriteVersionAndFeatures();
|
||||
void WriteVersionAndFeatures(bool is_vm_snapshot);
|
||||
|
||||
void Serialize();
|
||||
WriteStream* stream() { return &stream_; }
|
||||
|
|
|
@ -636,7 +636,9 @@ RawError* Dart::InitializeIsolate(const uint8_t* snapshot_data,
|
|||
return Error::null();
|
||||
}
|
||||
|
||||
const char* Dart::FeaturesString(Isolate* isolate, Snapshot::Kind kind) {
|
||||
const char* Dart::FeaturesString(Isolate* isolate,
|
||||
bool is_vm_isolate,
|
||||
Snapshot::Kind kind) {
|
||||
TextBuffer buffer(64);
|
||||
|
||||
// Different fields are included for DEBUG/RELEASE/PRODUCT.
|
||||
|
@ -648,16 +650,24 @@ const char* Dart::FeaturesString(Isolate* isolate, Snapshot::Kind kind) {
|
|||
buffer.AddString("release");
|
||||
#endif
|
||||
|
||||
if (Snapshot::IncludesCode(kind)) {
|
||||
// Checked mode affects deopt ids.
|
||||
#define ADD_FLAG(name, isolate_flag, flag) \
|
||||
do { \
|
||||
const bool name = (isolate != NULL) ? isolate->name() : flag; \
|
||||
buffer.AddString(name ? (" " #name) : (" no-" #name)); \
|
||||
} while (0);
|
||||
|
||||
// We don't write the strong flag into the features list for the VM isolate
|
||||
// snapshot as the implementation is in an intermediate state where the VM
|
||||
// isolate is always initialized from a vm_snapshot generated in non strong
|
||||
// mode.
|
||||
if (!is_vm_isolate) {
|
||||
ADD_FLAG(strong, strong, FLAG_strong);
|
||||
}
|
||||
|
||||
if (Snapshot::IncludesCode(kind)) {
|
||||
// Checked mode affects deopt ids.
|
||||
ADD_FLAG(type_checks, enable_type_checks, FLAG_enable_type_checks);
|
||||
ADD_FLAG(asserts, enable_asserts, FLAG_enable_asserts);
|
||||
ADD_FLAG(strong, strong, FLAG_strong);
|
||||
ADD_FLAG(error_on_bad_type, enable_error_on_bad_type,
|
||||
FLAG_error_on_bad_type);
|
||||
ADD_FLAG(error_on_bad_override, enable_error_on_bad_override,
|
||||
|
@ -666,7 +676,6 @@ const char* Dart::FeaturesString(Isolate* isolate, Snapshot::Kind kind) {
|
|||
ADD_FLAG(use_field_guards, use_field_guards, FLAG_use_field_guards);
|
||||
ADD_FLAG(use_osr, use_osr, FLAG_use_osr);
|
||||
}
|
||||
#undef ADD_FLAG
|
||||
|
||||
// Generated code must match the host architecture and ABI.
|
||||
#if defined(TARGET_ARCH_ARM)
|
||||
|
@ -697,6 +706,7 @@ const char* Dart::FeaturesString(Isolate* isolate, Snapshot::Kind kind) {
|
|||
if (FLAG_precompiled_mode && FLAG_dwarf_stack_traces) {
|
||||
buffer.AddString(" dwarf-stack-traces");
|
||||
}
|
||||
#undef ADD_FLAG
|
||||
|
||||
return buffer.Steal();
|
||||
}
|
||||
|
|
|
@ -74,7 +74,9 @@ class Dart : public AllStatic {
|
|||
static uword AllocateReadOnlyHandle();
|
||||
static bool IsReadOnlyHandle(uword address);
|
||||
|
||||
static const char* FeaturesString(Isolate* isolate, Snapshot::Kind kind);
|
||||
static const char* FeaturesString(Isolate* isolate,
|
||||
bool is_vm_snapshot,
|
||||
Snapshot::Kind kind);
|
||||
static Snapshot::Kind vm_snapshot_kind() { return vm_snapshot_kind_; }
|
||||
static const uint8_t* vm_snapshot_instructions() {
|
||||
return vm_snapshot_instructions_;
|
||||
|
|
|
@ -1551,6 +1551,37 @@ Dart_CreateScriptSnapshot(uint8_t** script_snapshot_buffer,
|
|||
return Api::Success();
|
||||
}
|
||||
|
||||
DART_EXPORT bool Dart_IsDart2Snapshot(uint8_t* snapshot_buffer,
|
||||
intptr_t snapshot_size) {
|
||||
const char* expected_version = Version::SnapshotString();
|
||||
ASSERT(expected_version != NULL);
|
||||
const intptr_t version_len = strlen(expected_version);
|
||||
if (snapshot_size < version_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* version = reinterpret_cast<const char*>(snapshot_buffer);
|
||||
ASSERT(version != NULL);
|
||||
if (strncmp(version, expected_version, version_len)) {
|
||||
return false;
|
||||
}
|
||||
const char* features =
|
||||
reinterpret_cast<const char*>(snapshot_buffer) + version_len;
|
||||
ASSERT(features != NULL);
|
||||
intptr_t pending_len = snapshot_size - version_len;
|
||||
intptr_t buffer_len = OS::StrNLen(features, pending_len);
|
||||
// if buffer_len is less than pending_len it means we have a null terminated
|
||||
// string and we can safely execute 'strstr' on it.
|
||||
if ((buffer_len < pending_len)) {
|
||||
if (strstr(features, "no-strong")) {
|
||||
return false;
|
||||
} else if (strstr(features, "strong")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DART_EXPORT void Dart_InterruptIsolate(Dart_Isolate isolate) {
|
||||
if (isolate == NULL) {
|
||||
FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
|
||||
|
|
|
@ -662,7 +662,7 @@ RawApiError* SnapshotReader::VerifyVersionAndFeatures(Isolate* isolate) {
|
|||
}
|
||||
Advance(version_len);
|
||||
|
||||
const char* expected_features = Dart::FeaturesString(isolate, kind_);
|
||||
const char* expected_features = Dart::FeaturesString(isolate, false, kind_);
|
||||
ASSERT(expected_features != NULL);
|
||||
const intptr_t expected_len = strlen(expected_features);
|
||||
|
||||
|
@ -1535,7 +1535,7 @@ void SnapshotWriter::WriteVersionAndFeatures() {
|
|||
WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
|
||||
|
||||
const char* expected_features =
|
||||
Dart::FeaturesString(Isolate::Current(), kind_);
|
||||
Dart::FeaturesString(Isolate::Current(), false, kind_);
|
||||
ASSERT(expected_features != NULL);
|
||||
const intptr_t features_len = strlen(expected_features);
|
||||
WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
|
||||
|
|
|
@ -1791,6 +1791,32 @@ VM_UNIT_TEST_CASE(MismatchedSnapshotKinds) {
|
|||
free(script_snapshot);
|
||||
}
|
||||
|
||||
VM_UNIT_TEST_CASE(CheckKernelSnapshot) {
|
||||
intptr_t vm_isolate_snapshot_size;
|
||||
uint8_t* isolate_snapshot = NULL;
|
||||
intptr_t isolate_snapshot_size;
|
||||
uint8_t* full_snapshot = NULL;
|
||||
bool saved_load_deferred_eagerly_mode = FLAG_load_deferred_eagerly;
|
||||
FLAG_load_deferred_eagerly = true;
|
||||
{
|
||||
// Start an Isolate, and create a full snapshot of it.
|
||||
TestIsolateScope __test_isolate__;
|
||||
Dart_EnterScope(); // Start a Dart API scope for invoking API functions.
|
||||
|
||||
// Write out the script snapshot.
|
||||
Dart_Handle result =
|
||||
Dart_CreateSnapshot(NULL, &vm_isolate_snapshot_size, &isolate_snapshot,
|
||||
&isolate_snapshot_size);
|
||||
EXPECT_VALID(result);
|
||||
full_snapshot = reinterpret_cast<uint8_t*>(malloc(isolate_snapshot_size));
|
||||
memmove(full_snapshot, isolate_snapshot, isolate_snapshot_size);
|
||||
Dart_ExitScope();
|
||||
}
|
||||
FLAG_load_deferred_eagerly = saved_load_deferred_eagerly_mode;
|
||||
bool is_kernel = Dart_IsDart2Snapshot(full_snapshot, isolate_snapshot_size);
|
||||
EXPECT_EQ(FLAG_strong, is_kernel);
|
||||
}
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
||||
// Helper function to call a top level Dart function and serialize the result.
|
||||
|
|
Loading…
Reference in a new issue