mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm/concurrency] Make an IsolateGroup object which will contain group-specific resources
The isolate group object will keep a doubly-linked list of all isolates within it's group. This will allow us to later on iterate all isolates within a group for e.g. GC purposes. The isolate group object will eventually hold the shared heap, thread registry and other resources. This CL is only the start. Issue https://github.com/dart-lang/sdk/issues/36097 Change-Id: I32103bbb4830cd4f16665c4032d47dabdf3594dd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108407 Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Alexander Aprelev <aam@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
24725a8559
commit
4c5028d139
|
@ -20,9 +20,13 @@ def CheckMemcpy(filename):
|
|||
content = fh.read()
|
||||
match = re.search('\\bmemcpy\\b', content)
|
||||
if match:
|
||||
line_number = content[0:match.start()].count('\n') + 1
|
||||
print("%s:%d: use of memcpy is forbidden" % (filename, line_number))
|
||||
return 1
|
||||
offset = match.start()
|
||||
end_of_line = content.index('\n', offset)
|
||||
# We allow explicit use of memcpy with an opt-in via NOLINT
|
||||
if 'NOLINT' not in content[offset:end_of_line]:
|
||||
line_number = content[0:match.start()].count('\n') + 1
|
||||
print("%s:%d: use of memcpy is forbidden" % (filename, line_number))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ class SpawnIsolateTask : public ThreadPool::Task {
|
|||
}
|
||||
|
||||
void Run() override {
|
||||
IsolateGroupSource* source = state_->source();
|
||||
auto group = state_->isolate_group();
|
||||
|
||||
// The create isolate group call back is mandatory. If not provided we
|
||||
// cannot spawn isolates.
|
||||
|
@ -152,7 +152,7 @@ class SpawnIsolateTask : public ThreadPool::Task {
|
|||
// Create a new isolate.
|
||||
char* error = nullptr;
|
||||
Isolate* isolate = nullptr;
|
||||
if (source == nullptr || initialize_callback == nullptr) {
|
||||
if (group == nullptr || initialize_callback == nullptr) {
|
||||
// Make a copy of the state's isolate flags and hand it to the callback.
|
||||
Dart_IsolateFlags api_flags = *(state_->isolate_flags());
|
||||
isolate = reinterpret_cast<Isolate*>((create_group_callback)(
|
||||
|
@ -166,7 +166,7 @@ class SpawnIsolateTask : public ThreadPool::Task {
|
|||
return;
|
||||
}
|
||||
|
||||
isolate = CreateIsolateFromExistingSource(source, name, &error);
|
||||
isolate = CreateWithinExistingIsolateGroup(group, name, &error);
|
||||
parent_isolate_->DecrementSpawnCount();
|
||||
parent_isolate_ = nullptr;
|
||||
if (isolate == nullptr) {
|
||||
|
@ -285,7 +285,7 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 11) {
|
|||
std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
|
||||
port.Id(), isolate->origin_id(), String2UTF8(script_uri), func,
|
||||
&message_buffer, utf8_package_config, paused.value(), fatal_errors,
|
||||
on_exit_port, on_error_port, utf8_debug_name, isolate->source()));
|
||||
on_exit_port, on_error_port, utf8_debug_name, isolate->group()));
|
||||
|
||||
// Since this is a call to Isolate.spawn, copy the parent isolate's code.
|
||||
state->isolate_flags()->copy_parent_code = true;
|
||||
|
@ -396,12 +396,10 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 13) {
|
|||
const char* utf8_debug_name =
|
||||
debugName.IsNull() ? NULL : String2UTF8(debugName);
|
||||
|
||||
IsolateGroupSource* null_source = nullptr;
|
||||
|
||||
std::unique_ptr<IsolateSpawnState> state(new IsolateSpawnState(
|
||||
port.Id(), canonical_uri, utf8_package_config, &arguments_buffer,
|
||||
&message_buffer, paused.value(), fatal_errors, on_exit_port,
|
||||
on_error_port, utf8_debug_name, null_source));
|
||||
on_error_port, utf8_debug_name, /*group=*/nullptr));
|
||||
|
||||
// If we were passed a value then override the default flags state for
|
||||
// checked mode.
|
||||
|
@ -470,7 +468,7 @@ static void ExternalTypedDataFinalizer(void* isolate_callback_data,
|
|||
free(peer);
|
||||
}
|
||||
|
||||
static intptr_t GetUint8SizeOrThrow(const Instance& instance) {
|
||||
static intptr_t GetTypedDataSizeOrThrow(const Instance& instance) {
|
||||
// From the Dart side we are guaranteed that the type of [instance] is a
|
||||
// subtype of TypedData.
|
||||
if (instance.IsTypedDataBase()) {
|
||||
|
@ -503,19 +501,18 @@ DEFINE_NATIVE_ENTRY(TransferableTypedData_factory, 0, 2) {
|
|||
UNREACHABLE();
|
||||
}
|
||||
Instance& instance = Instance::Handle();
|
||||
unsigned long long total_bytes = 0;
|
||||
const unsigned long kMaxBytes =
|
||||
TypedData::MaxElements(kTypedDataUint8ArrayCid);
|
||||
uint64_t total_bytes = 0;
|
||||
const uint64_t kMaxBytes = TypedData::MaxElements(kTypedDataUint8ArrayCid);
|
||||
for (intptr_t i = 0; i < array_length; i++) {
|
||||
instance ^= array.At(i);
|
||||
total_bytes += GetUint8SizeOrThrow(instance);
|
||||
total_bytes += static_cast<uintptr_t>(GetTypedDataSizeOrThrow(instance));
|
||||
if (total_bytes > kMaxBytes) {
|
||||
const Array& error_args = Array::Handle(Array::New(3));
|
||||
error_args.SetAt(0, array);
|
||||
error_args.SetAt(1, String::Handle(String::New("data")));
|
||||
error_args.SetAt(2,
|
||||
String::Handle(String::NewFormatted(
|
||||
"Aggregated list exceeds max size %ld", kMaxBytes)));
|
||||
error_args.SetAt(
|
||||
2, String::Handle(String::NewFormatted(
|
||||
"Aggregated list exceeds max size %" Pu64 "", kMaxBytes)));
|
||||
Exceptions::ThrowByType(Exceptions::kArgumentValue, error_args);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -539,11 +536,11 @@ DEFINE_NATIVE_ENTRY(TransferableTypedData_factory, 0, 2) {
|
|||
|
||||
void* source = typed_data.DataAddr(0);
|
||||
// The memory does not overlap.
|
||||
memcpy(data + offset, source, length_in_bytes);
|
||||
memcpy(data + offset, source, length_in_bytes); // NOLINT
|
||||
offset += length_in_bytes;
|
||||
}
|
||||
}
|
||||
ASSERT(static_cast<unsigned long>(offset) == total_bytes);
|
||||
ASSERT(static_cast<uintptr_t>(offset) == total_bytes);
|
||||
return TransferableTypedData::New(data, total_bytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -138,13 +138,13 @@ static constexpr dart::compiler::target::word ICData_owner_offset = 20;
|
|||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
|
||||
static constexpr dart::compiler::target::word
|
||||
ICData_receivers_static_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 8;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 12;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 20;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 44;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 4;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 20;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 28;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 52;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 12;
|
||||
static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
LinkedHashMap_deleted_keys_offset = 24;
|
||||
|
@ -491,13 +491,13 @@ static constexpr dart::compiler::target::word ICData_owner_offset = 40;
|
|||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
|
||||
static constexpr dart::compiler::target::word
|
||||
ICData_receivers_static_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 48;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 40;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 8;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 64;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 40;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 48;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 56;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 104;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 24;
|
||||
static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
LinkedHashMap_deleted_keys_offset = 48;
|
||||
|
@ -845,13 +845,13 @@ static constexpr dart::compiler::target::word ICData_owner_offset = 20;
|
|||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
|
||||
static constexpr dart::compiler::target::word
|
||||
ICData_receivers_static_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 8;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 12;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 20;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 44;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 4;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 20;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 28;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 52;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 12;
|
||||
static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
LinkedHashMap_deleted_keys_offset = 24;
|
||||
|
@ -1194,13 +1194,13 @@ static constexpr dart::compiler::target::word ICData_owner_offset = 40;
|
|||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
|
||||
static constexpr dart::compiler::target::word
|
||||
ICData_receivers_static_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 48;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 40;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 8;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 64;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 40;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 48;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 56;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 104;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 24;
|
||||
static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
LinkedHashMap_deleted_keys_offset = 48;
|
||||
|
@ -1551,13 +1551,13 @@ static constexpr dart::compiler::target::word ICData_owner_offset = 40;
|
|||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 52;
|
||||
static constexpr dart::compiler::target::word
|
||||
ICData_receivers_static_type_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 48;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 40;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 88;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 8;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 64;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 40;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 48;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 56;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 104;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 24;
|
||||
static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
|
||||
static constexpr dart::compiler::target::word
|
||||
LinkedHashMap_deleted_keys_offset = 48;
|
||||
|
@ -1835,13 +1835,13 @@ static constexpr dart::compiler::target::word ICData_owner_offset = 20;
|
|||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 28;
|
||||
static constexpr dart::compiler::target::word
|
||||
ICData_receivers_static_type_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 8;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 12;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 20;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 44;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 4;
|
||||
static constexpr dart::compiler::target::word Isolate_class_table_offset = 32;
|
||||
static constexpr dart::compiler::target::word Isolate_current_tag_offset = 16;
|
||||
static constexpr dart::compiler::target::word Isolate_default_tag_offset = 20;
|
||||
static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 24;
|
||||
static constexpr dart::compiler::target::word Isolate_object_store_offset = 28;
|
||||
static constexpr dart::compiler::target::word Isolate_single_step_offset = 52;
|
||||
static constexpr dart::compiler::target::word Isolate_user_tag_offset = 12;
|
||||
static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
|
||||
static constexpr dart::compiler::target::word
|
||||
LinkedHashMap_deleted_keys_offset = 24;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
// 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.
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "vm/dart.h"
|
||||
|
||||
#include "vm/clustered_snapshot.h"
|
||||
|
@ -234,7 +237,18 @@ char* Dart::Init(const uint8_t* vm_isolate_snapshot,
|
|||
// Setup default flags for the VM isolate.
|
||||
Dart_IsolateFlags api_flags;
|
||||
Isolate::FlagsInitialize(&api_flags);
|
||||
vm_isolate_ = Isolate::InitIsolate("vm-isolate", api_flags, is_vm_isolate);
|
||||
|
||||
// We make a fake [IsolateGroupSource] here, since the "vm-isolate" is not
|
||||
// really an isolate itself - it acts more as a container for VM-global
|
||||
// objects.
|
||||
std::unique_ptr<IsolateGroupSource> source(
|
||||
new IsolateGroupSource(nullptr, "vm-isolate", nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, -1, api_flags));
|
||||
auto group = new IsolateGroup(std::move(source), /*embedder_data=*/nullptr);
|
||||
vm_isolate_ =
|
||||
Isolate::InitIsolate("vm-isolate", group, api_flags, is_vm_isolate);
|
||||
group->set_initial_spawn_successful();
|
||||
|
||||
// Verify assumptions about executing in the VM isolate.
|
||||
ASSERT(vm_isolate_ == Isolate::Current());
|
||||
ASSERT(vm_isolate_ == Thread::Current()->isolate());
|
||||
|
@ -604,9 +618,11 @@ char* Dart::Cleanup() {
|
|||
}
|
||||
|
||||
Isolate* Dart::CreateIsolate(const char* name_prefix,
|
||||
const Dart_IsolateFlags& api_flags) {
|
||||
const Dart_IsolateFlags& api_flags,
|
||||
IsolateGroup* isolate_group) {
|
||||
// Create a new isolate.
|
||||
Isolate* isolate = Isolate::InitIsolate(name_prefix, api_flags);
|
||||
Isolate* isolate =
|
||||
Isolate::InitIsolate(name_prefix, isolate_group, api_flags);
|
||||
return isolate;
|
||||
}
|
||||
|
||||
|
@ -854,7 +870,7 @@ void Dart::RunShutdownCallback() {
|
|||
Thread* thread = Thread::Current();
|
||||
ASSERT(thread->execution_state() == Thread::kThreadInVM);
|
||||
Isolate* isolate = thread->isolate();
|
||||
void* isolate_group_data = isolate->source()->callback_data;
|
||||
void* isolate_group_data = isolate->group()->embedder_data();
|
||||
void* isolate_data = isolate->init_callback_data();
|
||||
Dart_IsolateShutdownCallback callback = Isolate::ShutdownCallback();
|
||||
if (callback != NULL) {
|
||||
|
|
|
@ -48,7 +48,8 @@ class Dart : public AllStatic {
|
|||
static char* Cleanup();
|
||||
|
||||
static Isolate* CreateIsolate(const char* name_prefix,
|
||||
const Dart_IsolateFlags& api_flags);
|
||||
const Dart_IsolateFlags& api_flags,
|
||||
IsolateGroup* isolate_group);
|
||||
|
||||
// Initialize an isolate, either from a snapshot, from a Kernel binary, or
|
||||
// from SDK library sources. If the snapshot_buffer is non-NULL,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "include/dart_native_api.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "lib/stacktrace.h"
|
||||
#include "platform/assert.h"
|
||||
|
@ -1068,13 +1069,14 @@ ISOLATE_METRIC_LIST(ISOLATE_METRIC_API);
|
|||
|
||||
// --- Isolates ---
|
||||
|
||||
static Dart_Isolate CreateIsolate(IsolateGroupSource* source,
|
||||
static Dart_Isolate CreateIsolate(IsolateGroup* group,
|
||||
const char* name,
|
||||
void* isolate_data,
|
||||
char** error) {
|
||||
CHECK_NO_ISOLATE(Isolate::Current());
|
||||
|
||||
Isolate* I = Dart::CreateIsolate(name, source->flags);
|
||||
auto source = group->source();
|
||||
Isolate* I = Dart::CreateIsolate(name, source->flags, group);
|
||||
if (I == NULL) {
|
||||
if (error != NULL) {
|
||||
*error = strdup("Isolate creation failed");
|
||||
|
@ -1111,8 +1113,6 @@ static Dart_Isolate CreateIsolate(IsolateGroupSource* source,
|
|||
T->ExitApiScope();
|
||||
}
|
||||
|
||||
I->set_source(source);
|
||||
|
||||
if (success) {
|
||||
// A Thread structure has been associated to the thread, we do the
|
||||
// safepoint transition explicitly here instead of using the
|
||||
|
@ -1130,17 +1130,18 @@ static Dart_Isolate CreateIsolate(IsolateGroupSource* source,
|
|||
return reinterpret_cast<Dart_Isolate>(NULL);
|
||||
}
|
||||
|
||||
Isolate* CreateIsolateFromExistingSource(IsolateGroupSource* source,
|
||||
const char* name,
|
||||
char** error) {
|
||||
Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
|
||||
const char* name,
|
||||
char** error) {
|
||||
API_TIMELINE_DURATION(Thread::Current());
|
||||
CHECK_NO_ISOLATE(Isolate::Current());
|
||||
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(
|
||||
CreateIsolate(source, name, /*isolate_data=*/nullptr, error));
|
||||
CreateIsolate(group, name, /*isolate_data=*/nullptr, error));
|
||||
if (isolate == nullptr) return nullptr;
|
||||
|
||||
RELEASE_ASSERT(isolate->source() == source);
|
||||
auto source = group->source();
|
||||
ASSERT(isolate->source() == source);
|
||||
|
||||
if (source->script_kernel_buffer != nullptr) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
@ -1210,15 +1211,14 @@ Dart_CreateIsolateGroup(const char* script_uri,
|
|||
}
|
||||
|
||||
const char* non_null_name = name == nullptr ? "isolate" : name;
|
||||
auto source = new IsolateGroupSource(script_uri, non_null_name, snapshot_data,
|
||||
snapshot_instructions, shared_data,
|
||||
shared_instructions, nullptr, -1, *flags,
|
||||
isolate_group_data);
|
||||
source->IncrementIsolateUsageCount();
|
||||
std::unique_ptr<IsolateGroupSource> source(new IsolateGroupSource(
|
||||
script_uri, non_null_name, snapshot_data, snapshot_instructions,
|
||||
shared_data, shared_instructions, nullptr, -1, *flags));
|
||||
auto group = new IsolateGroup(std::move(source), isolate_group_data);
|
||||
Dart_Isolate isolate =
|
||||
CreateIsolate(source, non_null_name, isolate_data, error);
|
||||
if (source->DecrementIsolateUsageCount()) {
|
||||
delete source;
|
||||
CreateIsolate(group, non_null_name, isolate_data, error);
|
||||
if (isolate != nullptr) {
|
||||
group->set_initial_spawn_successful();
|
||||
}
|
||||
return isolate;
|
||||
}
|
||||
|
@ -1241,14 +1241,14 @@ Dart_CreateIsolateGroupFromKernel(const char* script_uri,
|
|||
}
|
||||
|
||||
const char* non_null_name = name == nullptr ? "isolate" : name;
|
||||
auto source = new IsolateGroupSource(
|
||||
std::unique_ptr<IsolateGroupSource> source(new IsolateGroupSource(
|
||||
script_uri, non_null_name, nullptr, nullptr, nullptr, nullptr,
|
||||
kernel_buffer, kernel_buffer_size, *flags, isolate_group_data);
|
||||
source->IncrementIsolateUsageCount();
|
||||
kernel_buffer, kernel_buffer_size, *flags));
|
||||
auto group = new IsolateGroup(std::move(source), isolate_group_data);
|
||||
Dart_Isolate isolate =
|
||||
CreateIsolate(source, non_null_name, isolate_data, error);
|
||||
if (source->DecrementIsolateUsageCount()) {
|
||||
delete source;
|
||||
CreateIsolate(group, non_null_name, isolate_data, error);
|
||||
if (isolate != nullptr) {
|
||||
group->set_initial_spawn_successful();
|
||||
}
|
||||
return isolate;
|
||||
}
|
||||
|
@ -1308,7 +1308,7 @@ DART_EXPORT void* Dart_CurrentIsolateGroupData() {
|
|||
Isolate* isolate = Isolate::Current();
|
||||
CHECK_ISOLATE(isolate);
|
||||
NoSafepointScope no_safepoint_scope;
|
||||
return isolate->source()->callback_data;
|
||||
return isolate->group()->embedder_data();
|
||||
}
|
||||
|
||||
DART_EXPORT void* Dart_IsolateGroupData(Dart_Isolate isolate) {
|
||||
|
@ -1316,7 +1316,7 @@ DART_EXPORT void* Dart_IsolateGroupData(Dart_Isolate isolate) {
|
|||
FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
|
||||
}
|
||||
// TODO(http://dartbug.com/16615): Validate isolate parameter.
|
||||
return reinterpret_cast<Isolate*>(isolate)->source()->callback_data;
|
||||
return reinterpret_cast<Isolate*>(isolate)->group()->embedder_data();
|
||||
}
|
||||
|
||||
DART_EXPORT Dart_Handle Dart_DebugName() {
|
||||
|
|
|
@ -365,9 +365,9 @@ class IsolateGroupSource;
|
|||
|
||||
// Creates a new isolate from [source] (which should come from an existing
|
||||
// isolate).
|
||||
Isolate* CreateIsolateFromExistingSource(IsolateGroupSource* source,
|
||||
const char* name,
|
||||
char** error);
|
||||
Isolate* CreateWithinExistingIsolateGroup(IsolateGroup* group,
|
||||
const char* name,
|
||||
char** error);
|
||||
|
||||
} // namespace dart.
|
||||
|
||||
|
|
|
@ -130,6 +130,43 @@ static RawInstance* DeserializeMessage(Thread* thread, Message* message) {
|
|||
}
|
||||
}
|
||||
|
||||
IsolateGroup::IsolateGroup(std::unique_ptr<IsolateGroupSource> source,
|
||||
void* embedder_data)
|
||||
: source_(std::move(source)),
|
||||
embedder_data_(embedder_data),
|
||||
isolates_monitor_(new Monitor()),
|
||||
isolates_() {}
|
||||
|
||||
IsolateGroup::~IsolateGroup() {}
|
||||
|
||||
void IsolateGroup::RegisterIsolate(Isolate* isolate) {
|
||||
MonitorLocker ml(isolates_monitor_.get());
|
||||
isolates_.Append(isolate);
|
||||
isolate_count_++;
|
||||
}
|
||||
|
||||
void IsolateGroup::UnregisterIsolate(Isolate* isolate) {
|
||||
bool is_last_isolate = false;
|
||||
{
|
||||
MonitorLocker ml(isolates_monitor_.get());
|
||||
isolates_.Remove(isolate);
|
||||
isolate_count_--;
|
||||
is_last_isolate = isolate_count_ == 0;
|
||||
}
|
||||
if (is_last_isolate) {
|
||||
// If the creation of the isolate group (or the first isolate within the
|
||||
// isolate group) failed, we do not invoke the cleanup callback (the
|
||||
// embedder is responsible for handling the creation error).
|
||||
if (initial_spawn_successful_) {
|
||||
auto group_shutdown_callback = Isolate::GroupCleanupCallback();
|
||||
if (group_shutdown_callback != nullptr) {
|
||||
group_shutdown_callback(embedder_data());
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsolateVisitor::IsVMInternalIsolate(Isolate* isolate) const {
|
||||
return Isolate::IsVMInternalIsolate(isolate);
|
||||
}
|
||||
|
@ -863,7 +900,8 @@ void BaseIsolate::AssertCurrentThreadIsMutator() const {
|
|||
|
||||
// TODO(srdjan): Some Isolate monitors can be shared. Replace their usage with
|
||||
// that shared monitor.
|
||||
Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
||||
Isolate::Isolate(IsolateGroup* isolate_group,
|
||||
const Dart_IsolateFlags& api_flags)
|
||||
: BaseIsolate(),
|
||||
current_tag_(UserTag::null()),
|
||||
default_tag_(UserTag::null()),
|
||||
|
@ -929,6 +967,9 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
|
|||
}
|
||||
NOT_IN_PRECOMPILED(optimizing_background_compiler_ =
|
||||
new BackgroundCompiler(this));
|
||||
|
||||
isolate_group->RegisterIsolate(this);
|
||||
isolate_group_ = isolate_group;
|
||||
}
|
||||
|
||||
#undef REUSABLE_HANDLE_SCOPE_INIT
|
||||
|
@ -998,6 +1039,11 @@ Isolate::~Isolate() {
|
|||
}
|
||||
delete[] embedder_entry_points_;
|
||||
}
|
||||
|
||||
// Run isolate group specific cleanup function if the last isolate in an
|
||||
// isolate group died.
|
||||
isolate_group_->UnregisterIsolate(this);
|
||||
isolate_group_ = nullptr;
|
||||
}
|
||||
|
||||
void Isolate::InitVM() {
|
||||
|
@ -1014,9 +1060,10 @@ void Isolate::InitVM() {
|
|||
}
|
||||
|
||||
Isolate* Isolate::InitIsolate(const char* name_prefix,
|
||||
IsolateGroup* isolate_group,
|
||||
const Dart_IsolateFlags& api_flags,
|
||||
bool is_vm_isolate) {
|
||||
Isolate* result = new Isolate(api_flags);
|
||||
Isolate* result = new Isolate(isolate_group, api_flags);
|
||||
ASSERT(result != nullptr);
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
|
@ -1112,6 +1159,7 @@ Isolate* Isolate::InitIsolate(const char* name_prefix,
|
|||
if (ServiceIsolate::IsServiceIsolate(result)) {
|
||||
ServiceIsolate::SetServiceIsolate(nullptr);
|
||||
}
|
||||
|
||||
delete result;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1904,25 +1952,11 @@ void Isolate::Shutdown() {
|
|||
// as we are shutting down the isolate.
|
||||
Thread::ExitIsolate();
|
||||
|
||||
// The source is null iff the isolate is the "vm-isolate".
|
||||
ASSERT((source_ == nullptr) == (Dart::vm_isolate() == this));
|
||||
|
||||
if (source_ != nullptr) {
|
||||
// Run isolate specific cleanup function.
|
||||
// Run isolate specific cleanup function for all non "vm-isolate's.
|
||||
if (Dart::vm_isolate() != this) {
|
||||
Dart_IsolateCleanupCallback cleanup = Isolate::CleanupCallback();
|
||||
if (cleanup != nullptr) {
|
||||
cleanup(source_->callback_data, init_callback_data());
|
||||
}
|
||||
|
||||
// Run isolate group specific cleanup function if the last isolate in an
|
||||
// isolate group died.
|
||||
if (source_->DecrementIsolateUsageCount()) {
|
||||
auto group_cleanup_callback = Isolate::GroupCleanupCallback();
|
||||
if (group_cleanup_callback != nullptr) {
|
||||
group_cleanup_callback(source_->callback_data);
|
||||
}
|
||||
delete source_;
|
||||
source_ = nullptr;
|
||||
cleanup(isolate_group_->embedder_data(), init_callback_data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2891,6 +2925,7 @@ void Isolate::UnscheduleThread(Thread* thread,
|
|||
// so we create a MonitorLocker object which does not do any
|
||||
// no_safepoint_scope_depth increments/decrements.
|
||||
MonitorLocker ml(threads_lock(), false);
|
||||
|
||||
if (is_mutator) {
|
||||
if (thread->sticky_error() != Error::null()) {
|
||||
ASSERT(sticky_error_ == Error::null());
|
||||
|
@ -2954,7 +2989,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
Dart_Port on_exit_port,
|
||||
Dart_Port on_error_port,
|
||||
const char* debug_name,
|
||||
IsolateGroupSource* source)
|
||||
IsolateGroup* isolate_group)
|
||||
: isolate_(nullptr),
|
||||
parent_port_(parent_port),
|
||||
origin_id_(origin_id),
|
||||
|
@ -2966,7 +3001,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
class_name_(nullptr),
|
||||
function_name_(nullptr),
|
||||
debug_name_(debug_name),
|
||||
source_(source),
|
||||
isolate_group_(isolate_group),
|
||||
serialized_args_(nullptr),
|
||||
serialized_message_(message_buffer->StealMessage()),
|
||||
paused_(paused),
|
||||
|
@ -2999,7 +3034,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
Dart_Port on_exit_port,
|
||||
Dart_Port on_error_port,
|
||||
const char* debug_name,
|
||||
IsolateGroupSource* source)
|
||||
IsolateGroup* group)
|
||||
: isolate_(nullptr),
|
||||
parent_port_(parent_port),
|
||||
origin_id_(ILLEGAL_PORT),
|
||||
|
@ -3011,7 +3046,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
class_name_(nullptr),
|
||||
function_name_(nullptr),
|
||||
debug_name_(debug_name),
|
||||
source_(source),
|
||||
isolate_group_(group),
|
||||
serialized_args_(args_buffer->StealMessage()),
|
||||
serialized_message_(message_buffer->StealMessage()),
|
||||
isolate_flags_(),
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "vm/growable_array.h"
|
||||
#include "vm/handles.h"
|
||||
#include "vm/heap/verifier.h"
|
||||
#include "vm/intrusive_dlist.h"
|
||||
#include "vm/megamorphic_cache_table.h"
|
||||
#include "vm/metrics.h"
|
||||
#include "vm/os_thread.h"
|
||||
|
@ -181,8 +182,7 @@ class IsolateGroupSource {
|
|||
const uint8_t* shared_instructions,
|
||||
const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size,
|
||||
Dart_IsolateFlags flags,
|
||||
void* callback_data)
|
||||
Dart_IsolateFlags flags)
|
||||
: script_uri(script_uri),
|
||||
name(strdup(name)),
|
||||
snapshot_data(snapshot_data),
|
||||
|
@ -192,7 +192,6 @@ class IsolateGroupSource {
|
|||
kernel_buffer(kernel_buffer),
|
||||
kernel_buffer_size(kernel_buffer_size),
|
||||
flags(flags),
|
||||
callback_data(callback_data),
|
||||
script_kernel_buffer(nullptr),
|
||||
script_kernel_size(-1) {}
|
||||
~IsolateGroupSource() { free(name); }
|
||||
|
@ -208,26 +207,36 @@ class IsolateGroupSource {
|
|||
const uint8_t* kernel_buffer;
|
||||
const intptr_t kernel_buffer_size;
|
||||
Dart_IsolateFlags flags;
|
||||
void* callback_data;
|
||||
|
||||
// The kernel buffer used in `Dart_LoadScriptFromKernel`.
|
||||
const uint8_t* script_kernel_buffer;
|
||||
intptr_t script_kernel_size;
|
||||
|
||||
void IncrementIsolateUsageCount() {
|
||||
AtomicOperations::IncrementBy(&isolate_count_, 1);
|
||||
}
|
||||
|
||||
// Returns true if this was the last reference.
|
||||
bool DecrementIsolateUsageCount() {
|
||||
return AtomicOperations::FetchAndDecrement(&isolate_count_) == 1;
|
||||
}
|
||||
|
||||
private:
|
||||
intptr_t isolate_count_ = 0;
|
||||
};
|
||||
|
||||
class Isolate : public BaseIsolate {
|
||||
// Represents an isolate group and is shared among all isolates within a group.
|
||||
class IsolateGroup {
|
||||
public:
|
||||
IsolateGroup(std::unique_ptr<IsolateGroupSource> source, void* embedder_data);
|
||||
~IsolateGroup();
|
||||
|
||||
IsolateGroupSource* source() const { return source_.get(); }
|
||||
void* embedder_data() const { return embedder_data_; }
|
||||
|
||||
void set_initial_spawn_successful() { initial_spawn_successful_ = true; }
|
||||
|
||||
void RegisterIsolate(Isolate* isolate);
|
||||
void UnregisterIsolate(Isolate* isolate);
|
||||
|
||||
private:
|
||||
std::unique_ptr<IsolateGroupSource> source_;
|
||||
void* embedder_data_ = nullptr;
|
||||
std::unique_ptr<Monitor> isolates_monitor_;
|
||||
IntrusiveDList<Isolate> isolates_;
|
||||
intptr_t isolate_count_ = 0;
|
||||
bool initial_spawn_successful_ = false;
|
||||
};
|
||||
|
||||
class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
|
||||
public:
|
||||
// Keep both these enums in sync with isolate_patch.dart.
|
||||
// The different Isolate API message types.
|
||||
|
@ -311,12 +320,8 @@ class Isolate : public BaseIsolate {
|
|||
message_notify_callback_ = value;
|
||||
}
|
||||
|
||||
IsolateGroupSource* source() const { return source_; }
|
||||
|
||||
void set_source(IsolateGroupSource* source) {
|
||||
source->IncrementIsolateUsageCount();
|
||||
source_ = source;
|
||||
}
|
||||
IsolateGroupSource* source() const { return isolate_group_->source(); }
|
||||
IsolateGroup* group() const { return isolate_group_; }
|
||||
|
||||
bool HasPendingMessages();
|
||||
|
||||
|
@ -913,10 +918,11 @@ class Isolate : public BaseIsolate {
|
|||
friend class Dart; // Init, InitOnce, Shutdown.
|
||||
friend class IsolateKillerVisitor; // Kill().
|
||||
|
||||
explicit Isolate(const Dart_IsolateFlags& api_flags);
|
||||
Isolate(IsolateGroup* group, const Dart_IsolateFlags& api_flags);
|
||||
|
||||
static void InitVM();
|
||||
static Isolate* InitIsolate(const char* name_prefix,
|
||||
IsolateGroup* isolate_group,
|
||||
const Dart_IsolateFlags& api_flags,
|
||||
bool is_vm_isolate = false);
|
||||
|
||||
|
@ -984,6 +990,7 @@ class Isolate : public BaseIsolate {
|
|||
MarkingStack* marking_stack_ = nullptr;
|
||||
MarkingStack* deferred_marking_stack_ = nullptr;
|
||||
Heap* heap_ = nullptr;
|
||||
IsolateGroup* isolate_group_ = nullptr;
|
||||
|
||||
#define ISOLATE_FLAG_BITS(V) \
|
||||
V(ErrorsFatal) \
|
||||
|
@ -1167,7 +1174,6 @@ class Isolate : public BaseIsolate {
|
|||
static Monitor* isolates_list_monitor_;
|
||||
static Isolate* isolates_list_head_;
|
||||
static bool creation_enabled_;
|
||||
IsolateGroupSource* source_ = nullptr;
|
||||
|
||||
#define REUSABLE_FRIEND_DECLARATION(name) \
|
||||
friend class Reusable##name##HandleScope;
|
||||
|
@ -1242,7 +1248,7 @@ class IsolateSpawnState {
|
|||
Dart_Port onExit,
|
||||
Dart_Port onError,
|
||||
const char* debug_name,
|
||||
IsolateGroupSource* source);
|
||||
IsolateGroup* group);
|
||||
IsolateSpawnState(Dart_Port parent_port,
|
||||
const char* script_url,
|
||||
const char* package_config,
|
||||
|
@ -1253,7 +1259,7 @@ class IsolateSpawnState {
|
|||
Dart_Port onExit,
|
||||
Dart_Port onError,
|
||||
const char* debug_name,
|
||||
IsolateGroupSource* source);
|
||||
IsolateGroup* group);
|
||||
~IsolateSpawnState();
|
||||
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
|
@ -1278,7 +1284,7 @@ class IsolateSpawnState {
|
|||
RawInstance* BuildArgs(Thread* thread);
|
||||
RawInstance* BuildMessage(Thread* thread);
|
||||
|
||||
IsolateGroupSource* source() const { return source_; }
|
||||
IsolateGroup* isolate_group() const { return isolate_group_; }
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
|
@ -1292,7 +1298,7 @@ class IsolateSpawnState {
|
|||
const char* class_name_;
|
||||
const char* function_name_;
|
||||
const char* debug_name_;
|
||||
IsolateGroupSource* source_;
|
||||
IsolateGroup* isolate_group_;
|
||||
std::unique_ptr<Message> serialized_args_;
|
||||
std::unique_ptr<Message> serialized_message_;
|
||||
|
||||
|
|
Loading…
Reference in a new issue