dart-sdk/runtime/vm/service_isolate.cc

636 lines
20 KiB
C++
Raw Normal View History

// Copyright (c) 2015, 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.
#include "vm/service_isolate.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_message.h"
#include "vm/dart_entry.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/message.h"
#include "vm/message_handler.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/port.h"
#include "vm/service.h"
#include "vm/symbols.h"
#include "vm/thread_pool.h"
#include "vm/timeline.h"
#if !defined(PRODUCT)
namespace dart {
#define Z (T->zone())
DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests.");
DEFINE_FLAG(bool,
trace_service_pause_events,
false,
"Trace VM service isolate pause events.");
DEFINE_FLAG(bool,
trace_service_verbose,
false,
"Provide extra service tracing information.");
// These must be kept in sync with service/constants.dart
#define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0
#define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
#define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
#define VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID 3
#define VM_SERVICE_SERVER_INFO_MESSAGE_ID 4
#define VM_SERVICE_METHOD_CALL_FROM_NATIVE 5
static ArrayPtr MakeServiceControlMessage(Dart_Port port_id,
intptr_t code,
const String& name) {
const Array& list = Array::Handle(Array::New(4));
ASSERT(!list.IsNull());
const Integer& code_int = Integer::Handle(Integer::New(code));
const Integer& port_int = Integer::Handle(Integer::New(port_id));
const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
list.SetAt(0, code_int);
list.SetAt(1, port_int);
list.SetAt(2, send_port);
list.SetAt(3, name);
return list.ptr();
}
static ArrayPtr MakeServerControlMessage(const SendPort& sp,
intptr_t code,
bool enable,
const Bool& silenceOutput) {
const Array& list = Array::Handle(Array::New(4));
ASSERT(!list.IsNull());
list.SetAt(0, Integer::Handle(Integer::New(code)));
list.SetAt(1, sp);
list.SetAt(2, Bool::Get(enable));
list.SetAt(3, silenceOutput);
return list.ptr();
}
const char* ServiceIsolate::kName = DART_VM_SERVICE_ISOLATE_NAME;
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
Dart_IsolateGroupCreateCallback ServiceIsolate::create_group_callback_ = NULL;
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
Monitor* ServiceIsolate::monitor_ = new Monitor();
ServiceIsolate::State ServiceIsolate::state_ = ServiceIsolate::kStopped;
Isolate* ServiceIsolate::isolate_ = NULL;
Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT;
Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT;
char* ServiceIsolate::server_address_ = NULL;
char* ServiceIsolate::startup_failure_reason_ = nullptr;
void ServiceIsolate::RequestServerInfo(const SendPort& sp) {
const Array& message = Array::Handle(MakeServerControlMessage(
sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */,
Bool::Handle() /* ignored */));
ASSERT(!message.IsNull());
MessageWriter writer(false);
PortMap::PostMessage(
writer.WriteMessage(message, port_, Message::kNormalPriority));
}
void ServiceIsolate::ControlWebServer(const SendPort& sp,
bool enable,
const Bool& silenceOutput) {
const Array& message = Array::Handle(MakeServerControlMessage(
sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable, silenceOutput));
ASSERT(!message.IsNull());
MessageWriter writer(false);
PortMap::PostMessage(
writer.WriteMessage(message, port_, Message::kNormalPriority));
}
void ServiceIsolate::SetServerAddress(const char* address) {
if (server_address_ != NULL) {
free(server_address_);
server_address_ = NULL;
}
if (address == NULL) {
return;
}
server_address_ = Utils::StrDup(address);
}
bool ServiceIsolate::NameEquals(const char* name) {
ASSERT(name != NULL);
return strcmp(name, kName) == 0;
}
bool ServiceIsolate::Exists() {
MonitorLocker ml(monitor_);
return isolate_ != NULL;
}
bool ServiceIsolate::IsRunning() {
MonitorLocker ml(monitor_);
return (port_ != ILLEGAL_PORT) && (isolate_ != NULL);
}
bool ServiceIsolate::IsServiceIsolate(const Isolate* isolate) {
MonitorLocker ml(monitor_);
return isolate != nullptr && isolate == isolate_;
}
bool ServiceIsolate::IsServiceIsolateDescendant(Isolate* isolate) {
MonitorLocker ml(monitor_);
return isolate->origin_id() == origin_;
}
Dart_Port ServiceIsolate::Port() {
MonitorLocker ml(monitor_);
return port_;
}
void ServiceIsolate::WaitForServiceIsolateStartup() {
MonitorLocker ml(monitor_);
while (state_ == kStarting) {
ml.Wait();
}
}
bool ServiceIsolate::SendServiceRpc(uint8_t* request_json,
intptr_t request_json_length,
Dart_Port reply_port,
char** error) {
// Keep in sync with "sdk/lib/vmservice/vmservice.dart:_handleNativeRpcCall".
Dart_CObject opcode;
opcode.type = Dart_CObject_kInt32;
opcode.value.as_int32 = VM_SERVICE_METHOD_CALL_FROM_NATIVE;
Dart_CObject message;
message.type = Dart_CObject_kTypedData;
message.value.as_typed_data.type = Dart_TypedData_kUint8;
message.value.as_typed_data.length = request_json_length;
message.value.as_typed_data.values = request_json;
Dart_CObject send_port;
send_port.type = Dart_CObject_kSendPort;
send_port.value.as_send_port.id = reply_port;
send_port.value.as_send_port.origin_id = ILLEGAL_PORT;
Dart_CObject* request_array[] = {
&opcode,
&message,
&send_port,
};
Dart_CObject request;
request.type = Dart_CObject_kArray;
request.value.as_array.values = request_array;
request.value.as_array.length = ARRAY_SIZE(request_array);
ServiceIsolate::WaitForServiceIsolateStartup();
Dart_Port service_port = ServiceIsolate::Port();
const bool success = Dart_PostCObject(service_port, &request);
if (!success && error != nullptr) {
if (service_port == ILLEGAL_PORT) {
if (startup_failure_reason_ != nullptr) {
*error = OS::SCreate(/*zone=*/nullptr,
"Service isolate failed to start up: %s.",
startup_failure_reason_);
} else {
*error = Utils::StrDup("No service isolate port was found.");
}
} else {
*error = Utils::StrDup("Was unable to post message to service isolate.");
}
}
return success;
}
bool ServiceIsolate::SendIsolateStartupMessage() {
if (!IsRunning()) {
return false;
}
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
if (Dart::VmIsolateNameEquals(isolate->name())) {
return false;
}
ASSERT(isolate != NULL);
HANDLESCOPE(thread);
const String& name = String::Handle(String::New(isolate->name()));
ASSERT(!name.IsNull());
const Array& list = Array::Handle(MakeServiceControlMessage(
Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name));
ASSERT(!list.IsNull());
MessageWriter writer(false);
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Isolate %s %" Pd64
" registered.\n",
name.ToCString(), Dart_GetMainPortId());
}
return PortMap::PostMessage(
writer.WriteMessage(list, port_, Message::kNormalPriority));
}
bool ServiceIsolate::SendIsolateShutdownMessage() {
if (!IsRunning()) {
return false;
}
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
if (Dart::VmIsolateNameEquals(isolate->name())) {
return false;
}
ASSERT(isolate != NULL);
HANDLESCOPE(thread);
const String& name = String::Handle(String::New(isolate->name()));
ASSERT(!name.IsNull());
const Array& list = Array::Handle(MakeServiceControlMessage(
Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name));
ASSERT(!list.IsNull());
MessageWriter writer(false);
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Isolate %s %" Pd64
" deregistered.\n",
name.ToCString(), Dart_GetMainPortId());
}
return PortMap::PostMessage(
writer.WriteMessage(list, port_, Message::kNormalPriority));
}
void ServiceIsolate::SendServiceExitMessage() {
if (!IsRunning()) {
return;
}
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
": sending service exit message.\n");
}
Dart_CObject code;
code.type = Dart_CObject_kInt32;
code.value.as_int32 = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID;
Dart_CObject* values[1] = {&code};
Dart_CObject message;
message.type = Dart_CObject_kArray;
message.value.as_array.length = 1;
message.value.as_array.values = values;
ApiMessageWriter writer;
PortMap::PostMessage(
writer.WriteCMessage(&message, port_, Message::kNormalPriority));
}
void ServiceIsolate::SetServicePort(Dart_Port port) {
MonitorLocker ml(monitor_);
port_ = port;
}
void ServiceIsolate::SetServiceIsolate(Isolate* isolate) {
MonitorLocker ml(monitor_);
isolate_ = isolate;
if (isolate_ != NULL) {
isolate_->set_is_service_isolate(true);
origin_ = isolate_->origin_id();
}
}
void ServiceIsolate::MaybeMakeServiceIsolate(Isolate* I) {
Thread* T = Thread::Current();
ASSERT(I == T->isolate());
ASSERT(I != NULL);
ASSERT(I->name() != NULL);
if (!ServiceIsolate::NameEquals(I->name())) {
// Not service isolate.
return;
}
if (Exists()) {
// Service isolate already exists.
return;
}
SetServiceIsolate(I);
}
void ServiceIsolate::FinishedExiting() {
MonitorLocker ml(monitor_);
ASSERT(state_ == kStarted || state_ == kStopping);
state_ = kStopped;
ml.NotifyAll();
}
void ServiceIsolate::FinishedInitializing() {
MonitorLocker ml(monitor_);
ASSERT(state_ == kStarting);
state_ = kStarted;
ml.NotifyAll();
}
void ServiceIsolate::InitializingFailed(char* error) {
MonitorLocker ml(monitor_);
ASSERT(state_ == kStarting);
state_ = kStopped;
startup_failure_reason_ = error;
ml.NotifyAll();
}
class RunServiceTask : public ThreadPool::Task {
public:
virtual void Run() {
ASSERT(Isolate::Current() == NULL);
#if defined(SUPPORT_TIMELINE)
TimelineBeginEndScope tbes(Timeline::GetVMStream(),
"ServiceIsolateStartup");
#endif // SUPPORT_TIMELINE
char* error = NULL;
Isolate* isolate = NULL;
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
const auto create_group_callback = ServiceIsolate::create_group_callback();
ASSERT(create_group_callback != NULL);
Dart_IsolateFlags api_flags;
Isolate::FlagsInitialize(&api_flags);
api_flags.is_system_isolate = true;
isolate = reinterpret_cast<Isolate*>(
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
create_group_callback(ServiceIsolate::kName, ServiceIsolate::kName,
NULL, NULL, &api_flags, NULL, &error));
if (isolate == NULL) {
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
": Isolate creation error: %s\n",
error);
}
char* formatted_error = OS::SCreate(
/*zone=*/nullptr, "Invoking the 'create_group' failed with: '%s'",
error);
free(error);
error = nullptr;
ServiceIsolate::InitializingFailed(formatted_error);
return;
}
bool got_unwind;
{
ASSERT(Isolate::Current() == NULL);
StartIsolateScope start_scope(isolate);
got_unwind = RunMain(isolate);
}
// FinishedInitializing should be called irrespective of whether
// running main caused an error or not. Otherwise, other isolates
// waiting for service isolate to come up will deadlock.
ServiceIsolate::FinishedInitializing();
if (got_unwind) {
ShutdownIsolate(reinterpret_cast<uword>(isolate));
return;
}
isolate->message_handler()->Run(Dart::thread_pool(), NULL, ShutdownIsolate,
reinterpret_cast<uword>(isolate));
}
protected:
static void ShutdownIsolate(uword parameter) {
if (FLAG_trace_service) {
OS::PrintErr("vm-service: ShutdownIsolate\n");
}
Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(parameter));
{
auto T = Thread::Current();
TransitionNativeToVM transition(T);
StackZone zone(T);
HandleScope handle_scope(T);
auto I = T->isolate();
ASSERT(ServiceIsolate::IsServiceIsolate(I));
// Print the error if there is one. This may execute dart code to
// print the exception object, so we need to use a StartIsolateScope.
Error& error = Error::Handle(Z);
error = T->sticky_error();
if (!error.IsNull() && !error.IsUnwindError()) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Error: %s\n",
error.ToErrorCString());
}
Revert "[vm] Cleanup Dart_Get/Set/HasStickyError API and use isolate's sticky error only as a backup for thread's sticky error" This reverts commit b10f17960890b053a5c1ac9303e0f9332fc8bd17. Reason for revert: failed service/* tests Original change's description: > [vm] Cleanup Dart_Get/Set/HasStickyError API and use isolate's sticky error only as a backup for thread's sticky error > > Both thread and isolate have sticky error fields. Dart API was using > isolate's sticky error, while Dart code was using thread's sticky error. > There was a one-way move of a thread's sticky error into isolate > when thread was unscheduled. > > This causes a problem as error in the isolate may go unnoticed and > repeated unscheduling/re-scheduling might end up overwriting the error > in the isolate (which triggers the assertion). > > To solve this problem, this CL: > * Cleans up Dart API which manipulates isolate's sticky error, so > isolate's sticky error is never set directly. > * When sceduling an isolate to a thread, sticky error is moved back from > isolate (if any). > > With this changes, thread's sticky error is always used if thread is running, > and isolate's sticky error is only used to hold sticky error while > isolate has no thread. > > Fixes https://github.com/dart-lang/sdk/issues/35590 > > Change-Id: I99b128cac363ca2df75f6e64c083b1ec36c866ce > Reviewed-on: https://dart-review.googlesource.com/c/89442 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Alexander Markov <alexmarkov@google.com> TBR=rmacnak@google.com,alexmarkov@google.com,zra@google.com,asiva@google.com Change-Id: I15874575b6b8ddca618741c59c21d4e692c4dcab No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/90127 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
2019-01-18 01:41:18 +00:00
error = I->sticky_error();
if (!error.IsNull() && !error.IsUnwindError()) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Error: %s\n",
error.ToErrorCString());
Revert "[vm] Cleanup Dart_Get/Set/HasStickyError API and use isolate's sticky error only as a backup for thread's sticky error" This reverts commit b10f17960890b053a5c1ac9303e0f9332fc8bd17. Reason for revert: failed service/* tests Original change's description: > [vm] Cleanup Dart_Get/Set/HasStickyError API and use isolate's sticky error only as a backup for thread's sticky error > > Both thread and isolate have sticky error fields. Dart API was using > isolate's sticky error, while Dart code was using thread's sticky error. > There was a one-way move of a thread's sticky error into isolate > when thread was unscheduled. > > This causes a problem as error in the isolate may go unnoticed and > repeated unscheduling/re-scheduling might end up overwriting the error > in the isolate (which triggers the assertion). > > To solve this problem, this CL: > * Cleans up Dart API which manipulates isolate's sticky error, so > isolate's sticky error is never set directly. > * When sceduling an isolate to a thread, sticky error is moved back from > isolate (if any). > > With this changes, thread's sticky error is always used if thread is running, > and isolate's sticky error is only used to hold sticky error while > isolate has no thread. > > Fixes https://github.com/dart-lang/sdk/issues/35590 > > Change-Id: I99b128cac363ca2df75f6e64c083b1ec36c866ce > Reviewed-on: https://dart-review.googlesource.com/c/89442 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Alexander Markov <alexmarkov@google.com> TBR=rmacnak@google.com,alexmarkov@google.com,zra@google.com,asiva@google.com Change-Id: I15874575b6b8ddca618741c59c21d4e692c4dcab No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/90127 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
2019-01-18 01:41:18 +00:00
}
}
Dart_ShutdownIsolate();
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME ": Shutdown.\n");
}
ServiceIsolate::FinishedExiting();
}
bool RunMain(Isolate* I) {
Thread* T = Thread::Current();
ASSERT(I == T->isolate());
StackZone zone(T);
HANDLESCOPE(T);
// Invoke main which will set up the service port.
const Library& root_library =
Library::Handle(Z, I->group()->object_store()->root_library());
if (root_library.IsNull()) {
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
": Embedder did not install a script.");
}
// Service isolate is not supported by embedder.
return false;
}
ASSERT(!root_library.IsNull());
const String& entry_name = String::Handle(Z, String::New("main"));
ASSERT(!entry_name.IsNull());
const Function& entry = Function::Handle(
Z, root_library.LookupFunctionAllowPrivate(entry_name));
if (entry.IsNull()) {
// Service isolate is not supported by embedder.
if (FLAG_trace_service) {
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
": Embedder did not provide a main function.");
}
return false;
}
ASSERT(!entry.IsNull());
const Object& result = Object::Handle(
Z, DartEntry::InvokeFunction(entry, Object::empty_array()));
if (result.IsError()) {
// Service isolate did not initialize properly.
if (FLAG_trace_service) {
const Error& error = Error::Cast(result);
OS::PrintErr(DART_VM_SERVICE_ISOLATE_NAME
": Calling main resulted in an error: %s",
error.ToErrorCString());
}
if (result.IsUnwindError()) {
return true;
}
return false;
}
return false;
}
};
void ServiceIsolate::Run() {
{
MonitorLocker ml(monitor_);
ASSERT(state_ == kStopped);
state_ = kStarting;
ml.NotifyAll();
}
// Grab the isolate create callback here to avoid race conditions with tests
// that change this after Dart_Initialize returns.
Second attempt to reland "[vm/concurrency] Introduce concept of Isolate Groups" This reverts commit 3d14b75f972ca287cd892ff907cf04b22839af59. An Isolate Group (IG) is a collection of isolates which were spawned from the same source. This allows the VM to: * have a guarantee that all isolates within one IG can safely exchange structured objects (currently we rely on embedder for this guarantee) * hot-reload all isolates together (currently we only reload one isolate, leaving same-source isolates in inconsistent state) * make a shared heap for all isolates from the same IG, which paves the way for faster communication and sharing of immutable objects. All isolates within one IG will share the same IsolateGroupSource. **Embedder changes** This change makes breaking embedder API changes to support this new concept of Isolate Groups: The existing isolate lifecycle callbacks given to Dart_Initialize will become Isolate Group lifecycle callbacks. A new callback `initialize_isolate` callback will be added which can initialize a new isolate within an existing IG. Existing embedders can be updated by performing the following renames Dart_CreateIsolate -> Dart_CreateIsolateGroup Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData Dart_IsolateData -> Dart_IsolateGroupData Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData Dart_InitializeParams.create -> Dart_InitializeParams.create_group Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate By default `Isolate.spawn` will cause the creation of a new IG. Though an embedder can opt-into supporting multiple isolates within one IG by providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`. The responsibility of this new callback is to initialize an existing isolate (which was setup by re-using source code from the spawning isolate - i.e. the one which used `Isolate.spawn`) by setting native resolvers, initializing global state, etc. Issue https://github.com/dart-lang/sdk/issues/36648 Issue https://github.com/dart-lang/sdk/issues/36097 Original review: https://dart-review.googlesource.com/c/sdk/+/105241 Difference to original review: * Give each isolate it's own [Loader] (for now) * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate) * Fix IsolateData memory leak if isolate startup fails Difference to first reland(Patchset 2): * Fix typo where memory was freed twice. Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-07-08 23:49:05 +00:00
create_group_callback_ = Isolate::CreateGroupCallback();
if (create_group_callback_ == NULL) {
ServiceIsolate::InitializingFailed(
Utils::StrDup("The 'create_group' callback was not provided"));
return;
}
bool task_started = Dart::thread_pool()->Run<RunServiceTask>();
ASSERT(task_started);
}
void ServiceIsolate::KillServiceIsolate() {
{
MonitorLocker ml(monitor_);
if (state_ == kStopped) {
return;
}
ASSERT(state_ == kStarted);
state_ = kStopping;
ml.NotifyAll();
}
Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg);
{
MonitorLocker ml(monitor_);
while (state_ == kStopping) {
ml.Wait();
}
ASSERT(state_ == kStopped);
}
}
void ServiceIsolate::Shutdown() {
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
{
MonitorLocker ml(monitor_);
while (state_ == kStarting) {
ml.Wait();
}
}
if (IsRunning()) {
{
MonitorLocker ml(monitor_);
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
ASSERT(state_ == kStarted);
state_ = kStopping;
ml.NotifyAll();
}
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
SendServiceExitMessage();
{
MonitorLocker ml(monitor_);
while (state_ == kStopping) {
ml.Wait();
}
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
ASSERT(state_ == kStopped);
}
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
} else {
if (isolate_ != NULL) {
// TODO(johnmccutchan,turnidge) When it is possible to properly create
// the VMService object and set up its shutdown handler in the service
// isolate's main() function, this case will no longer be possible and
// can be removed.
KillServiceIsolate();
}
}
Revert "[vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them" This reverts commit d9a306fc59c36e143d332983630839d5c9b14dbc. Reason for revert: ================================================================= ==176913==ERROR: LeakSanitizer: detected memory leaks Direct leak of 13 byte(s) in 1 object(s) allocated from: #0 0x55d94882d540 in __interceptor_strdup /b/s/w/ir/kitchen-workdir/llvm-project/compiler-rt/lib/asan/asan_interceptors.cc:447:3 #1 0x55d9491abcd7 in dart::KernelIsolate::AddExperimentalFlag(char const*) ../../out/DebugX64/../../runtime/vm/kernel_isolate.cc:382:28 #2 0x55d9490af7d2 in dart::Flags::SetFlagFromString(dart::Flag*, char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:338:7 #3 0x55d9490b0221 in dart::Flags::Parse(char const*) ../../out/DebugX64/../../runtime/vm/flags.cc:399:12 #4 0x55d9490b0538 in dart::Flags::ProcessCommandLineFlags(int, char const**) ../../out/DebugX64/../../runtime/vm/flags.cc:438:5 #5 0x55d9488885df in dart::bin::main(int, char**) ../../out/DebugX64/../../runtime/bin/main.cc:1149:11 #6 0x55d94888ad9a in main ../../out/DebugX64/../../runtime/bin/main.cc:1245:3 #7 0x7f5ccc4a452a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2352a) SUMMARY: AddressSanitizer: 13 byte(s) leaked in 1 allocation(s). Original change's description: > [vm] Avoid allocating monitors globally - embedders in certain situations will run into reported leakes due to them > > Change-Id: Ied0446aebfdd8fb7e15c510cdf4160ff9ad013a6 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122148 > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Commit-Queue: Martin Kustermann <kustermann@google.com> TBR=kustermann@google.com,rmacnak@google.com,asiva@google.com Change-Id: I2c98bf7e0e565c6f8c016b4832d5587868c65a83 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122680 Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Aart Bik <ajcbik@google.com>
2019-10-23 19:34:28 +00:00
if (server_address_ != NULL) {
free(server_address_);
server_address_ = NULL;
}
if (startup_failure_reason_ != nullptr) {
free(startup_failure_reason_);
startup_failure_reason_ = nullptr;
}
}
void ServiceIsolate::BootVmServiceLibrary() {
Thread* thread = Thread::Current();
const Library& vmservice_library =
Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService()));
ASSERT(!vmservice_library.IsNull());
const String& boot_function_name = String::Handle(String::New("boot"));
const Function& boot_function = Function::Handle(
vmservice_library.LookupFunctionAllowPrivate(boot_function_name));
ASSERT(!boot_function.IsNull());
const Object& result = Object::Handle(
DartEntry::InvokeFunction(boot_function, Object::empty_array()));
ASSERT(!result.IsNull());
if (result.IsUnwindError() || result.IsUnhandledException()) {
Exceptions::PropagateError(Error::Cast(result));
}
Dart_Port port = ILLEGAL_PORT;
if (result.IsReceivePort()) {
port = ReceivePort::Cast(result).Id();
}
ASSERT(port != ILLEGAL_PORT);
ServiceIsolate::SetServicePort(port);
}
void ServiceIsolate::RegisterRunningIsolates(
const GrowableArray<Dart_Port>& isolate_ports,
const GrowableArray<const String*>& isolate_names) {
auto thread = Thread::Current();
auto zone = thread->zone();
ASSERT(ServiceIsolate::IsServiceIsolate(thread->isolate()));
// Obtain "_registerIsolate" function to call.
const String& library_url = Symbols::DartVMService();
ASSERT(!library_url.IsNull());
const Library& library =
Library::Handle(zone, Library::LookupLibrary(thread, library_url));
ASSERT(!library.IsNull());
const String& function_name =
String::Handle(zone, String::New("_registerIsolate"));
ASSERT(!function_name.IsNull());
const Function& register_function_ =
Function::Handle(zone, library.LookupFunctionAllowPrivate(function_name));
ASSERT(!register_function_.IsNull());
Integer& port_int = Integer::Handle(zone);
SendPort& send_port = SendPort::Handle(zone);
Array& args = Array::Handle(zone, Array::New(3));
Object& result = Object::Handle(zone);
ASSERT(isolate_ports.length() == isolate_names.length());
for (intptr_t i = 0; i < isolate_ports.length(); ++i) {
const Dart_Port port_id = isolate_ports[i];
const String& name = *isolate_names[i];
port_int = Integer::New(port_id);
send_port = SendPort::New(port_id);
args.SetAt(0, port_int);
args.SetAt(1, send_port);
args.SetAt(2, name);
result = DartEntry::InvokeFunction(register_function_, args);
if (FLAG_trace_service) {
OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
name.ToCString(), port_id);
}
ASSERT(!result.IsError());
}
}
void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {}
} // namespace dart
#endif // !defined(PRODUCT)