Version 2.15.0-294.0.dev
Merge commit '6828fd752e71c3e95118f65e69166c85aac730e2' into 'dev'
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index f3bb2bd..3569eb9 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -111,8 +111,9 @@
// We have to check whether the reciever has the same isolate group (e.g.
// native message handlers such as an IOService handler does not but does
// share the same origin port).
- const bool same_group = PortMap::IsReceiverInThisIsolateGroup(
- destination_port_id, isolate->group());
+ const bool same_group =
+ FLAG_enable_isolate_groups && PortMap::IsReceiverInThisIsolateGroup(
+ destination_port_id, isolate->group());
// TODO(turnidge): Throw an exception when the return value is false?
PortMap::PostMessage(WriteMessage(can_send_any_object, same_group, obj,
destination_port_id,
@@ -638,7 +639,7 @@
ASSERT(name != nullptr);
auto group = state_->isolate_group();
- if (group == nullptr) {
+ if (!FLAG_enable_isolate_groups || group == nullptr) {
RunHeavyweight(name);
} else {
RunLightweight(name);
@@ -675,7 +676,8 @@
}
void RunLightweight(const char* name) {
- // The create isolate initialize callback is mandatory.
+ // The create isolate initialize callback is mandatory if
+ // --enable-isolate-groups was passed.
auto initialize_callback = Isolate::InitializeCallback();
if (initialize_callback == nullptr) {
FailedSpawn(
@@ -932,16 +934,22 @@
const auto& func = Function::Handle(zone, GetTopLevelFunction(zone, closure));
PersistentHandle* closure_tuple_handle = nullptr;
if (func.IsNull()) {
- // We have a non-toplevel closure that we might need to copy.
- // Result will be [<closure-copy>, <objects-in-msg-to-rehash>]
- const auto& closure_copy_tuple = Object::Handle(
- zone, CopyMutableObjectGraph(closure)); // Throws if it fails.
- ASSERT(closure_copy_tuple.IsArray());
- ASSERT(Object::Handle(zone, Array::Cast(closure_copy_tuple).At(0))
- .IsClosure());
- closure_tuple_handle =
- isolate->group()->api_state()->AllocatePersistentHandle();
- closure_tuple_handle->set_ptr(closure_copy_tuple.ptr());
+ if (!FLAG_enable_isolate_groups) {
+ const String& msg = String::Handle(String::New(
+ "Isolate.spawn expects to be passed a static or top-level function"));
+ Exceptions::ThrowArgumentError(msg);
+ } else {
+ // We have a non-toplevel closure that we might need to copy.
+ // Result will be [<closure-copy>, <objects-in-msg-to-rehash>]
+ const auto& closure_copy_tuple = Object::Handle(
+ zone, CopyMutableObjectGraph(closure)); // Throws if it fails.
+ ASSERT(closure_copy_tuple.IsArray());
+ ASSERT(Object::Handle(zone, Array::Cast(closure_copy_tuple).At(0))
+ .IsClosure());
+ closure_tuple_handle =
+ isolate->group()->api_state()->AllocatePersistentHandle();
+ closure_tuple_handle->set_ptr(closure_copy_tuple.ptr());
+ }
}
bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value();
@@ -952,8 +960,9 @@
// serializable this will throw an exception.
SerializedObjectBuffer message_buffer;
message_buffer.set_message(WriteMessage(
- /*can_send_any_object=*/true,
- /*same_group=*/true, message, ILLEGAL_PORT, Message::kNormalPriority));
+ /* can_send_any_object */ true,
+ /* same_group */ FLAG_enable_isolate_groups, message, ILLEGAL_PORT,
+ Message::kNormalPriority));
const char* utf8_package_config =
packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 5b08899..1ec2adc 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -211,7 +211,7 @@
ASSERT(thread->IsMutatorThread());
const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0));
- {
+ if (FLAG_enable_isolate_groups) {
// Another isolate's mutator thread may have created [function] and
// published it via an ICData, MegamorphicCache etc. Entering the lock below
// is an acquire operation that pairs with the release operation when the
@@ -220,6 +220,12 @@
SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
}
+ // In single-isolate scenarios the lazy compile stub is only invoked if
+ // there's no existing code. In multi-isolate scenarios with shared JITed code
+ // we can end up in the lazy compile runtime entry here with code being
+ // installed.
+ ASSERT(!function.HasCode() || FLAG_enable_isolate_groups);
+
// Will throw if compilation failed (e.g. with compile-time error).
function.EnsureHasCode();
}
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 88dc441..1c7026a 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1463,6 +1463,13 @@
*error = nullptr;
+ if (!FLAG_enable_isolate_groups) {
+ *error = Utils::StrDup(
+ "Lightweight isolates need to be explicitly enabled by passing "
+ "--enable-isolate-groups.");
+ return nullptr;
+ }
+
Isolate* isolate;
isolate = CreateWithinExistingIsolateGroup(member->group(), name, error);
if (isolate != nullptr) {
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index eccc2ac..224a6b1 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -194,6 +194,7 @@
P(retain_code_objects, bool, true, \
"Serialize all code objects even if not otherwise " \
"needed in the precompiled runtime.") \
+ P(enable_isolate_groups, bool, true, "Enable isolate group support.") \
P(show_invisible_frames, bool, false, \
"Show invisible frames in stack traces.") \
D(trace_cha, bool, false, "Trace CHA operations") \
diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc
index c45765c..b30bf66 100644
--- a/runtime/vm/heap/heap_test.cc
+++ b/runtime/vm/heap/heap_test.cc
@@ -574,6 +574,9 @@
};
VM_UNIT_TEST_CASE(CleanupBequestNeverReceived) {
+ // This test uses features from isolate groups
+ FLAG_enable_isolate_groups = true;
+
const char* TEST_MESSAGE = "hello, world";
Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
EXPECT_EQ(parent, Dart_CurrentIsolate());
@@ -605,6 +608,9 @@
}
VM_UNIT_TEST_CASE(ReceivesSendAndExitMessage) {
+ // This test uses features from isolate groups
+ FLAG_enable_isolate_groups = true;
+
const char* TEST_MESSAGE = "hello, world";
Dart_Isolate parent = TestCase::CreateTestIsolate("parent");
EXPECT_EQ(parent, Dart_CurrentIsolate());
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 3f425e4..c1e6cbe 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2638,9 +2638,11 @@
Dart::thread_pool()->Run<ShutdownGroupTask>(isolate_group);
}
} else {
- // TODO(dartbug.com/36097): An isolate just died. A significant amount of
- // memory might have become unreachable. We should evaluate how to best
- // inform the GC about this situation.
+ if (FLAG_enable_isolate_groups) {
+ // TODO(dartbug.com/36097): An isolate just died. A significant amount of
+ // memory might have become unreachable. We should evaluate how to best
+ // inform the GC about this situation.
+ }
}
} // namespace dart
@@ -2805,6 +2807,11 @@
auto thread = Thread::Current();
StoppedMutatorsScope stopped_mutators_scope(thread);
+ if (thread->IsMutatorThread() && !FLAG_enable_isolate_groups) {
+ single_current_mutator->Call();
+ return;
+ }
+
if (thread->IsAtSafepoint()) {
RELEASE_ASSERT(safepoint_handler()->IsOwnedByTheThread(thread));
single_current_mutator->Call();
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index c693c02..549dd9b 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -869,6 +869,9 @@
new_cache.WriteEntryToBuffer(zone, &buffer, colliding_index, " ");
THR_Print("%s\n", buffer.buffer());
}
+ if (!FLAG_enable_isolate_groups) {
+ FATAL("Duplicate subtype test cache entry");
+ }
if (old_result.ptr() != result.ptr()) {
FATAL("Existing subtype test cache entry has result %s, not %s",
old_result.ToCString(), result.ToCString());
@@ -1243,6 +1246,9 @@
const Code& target_code = Code::Handle(zone, target_function.EnsureHasCode());
// Before patching verify that we are not repeatedly patching to the same
// target.
+ ASSERT(FLAG_enable_isolate_groups ||
+ target_code.ptr() != CodePatcher::GetStaticCallTargetAt(
+ caller_frame->pc(), caller_code));
if (target_code.ptr() !=
CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)) {
GcSafepointOperationScope safepoint(thread);
@@ -3012,6 +3018,10 @@
current_target_code.EntryPoint(),
current_target_code.is_optimized() ? "optimized" : "unoptimized");
}
+ // With isolate groups enabled, it is possible that the target code
+ // has been deactivated just now(as a result of re-optimizatin for example),
+ // which will result in another run through FixCallersTarget.
+ ASSERT(!current_target_code.IsDisabled() || FLAG_enable_isolate_groups);
arguments.SetReturn(current_target_code);
#else
UNREACHABLE();
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index a60edfa..673f26e 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -401,6 +401,11 @@
// cases.
if (thread->IsAtSafepoint()) {
RELEASE_ASSERT(group->safepoint_handler()->IsOwnedByTheThread(thread));
+ // In DEBUG mode the snapshot writer also calls this method inside a
+ // safepoint.
+#if !defined(DEBUG)
+ RELEASE_ASSERT(FLAG_enable_isolate_groups || !USING_PRODUCT);
+#endif
data = object_store->symbol_table();
CanonicalStringSet table(&key, &value, &data);
symbol ^= table.GetOrNull(str);
diff --git a/tools/VERSION b/tools/VERSION
index 8738c13..80c6a13 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 293
+PRERELEASE 294
PRERELEASE_PATCH 0
\ No newline at end of file