Files
sdk/runtime/bin/loader.h
T
Vyacheslav Egorov 3d14b75f97 Revert "Reland "[vm/concurrency] Introduce concept of Isolate Groups""
This reverts commit 67ab3be10d.

Reason for revert: Causes non-deterministic failures on front-end bots on Windows with "Isolate creation failed" error. See https://logs.chromium.org/logs/dart/buildbucket/cr-buildbucket.appspot.com/8909292129328681248/+/steps/unit_tests/0/stdout

Original change's description:
> Reland "[vm/concurrency] Introduce concept of Isolate Groups"
> 
> 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
> 
> Change-Id: I98277d3d10fe275aa9b8a16b6bdd446bbea0b100
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107506
> Commit-Queue: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>

TBR=kustermann@google.com,aam@google.com,rmacnak@google.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Change-Id: Ia4e0f4f9fc317499d3570a371c5bdf9aed799e77
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108101
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
2019-07-03 12:19:15 +00:00

160 lines
5.6 KiB
C++

// Copyright (c) 2016, 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.
#ifndef RUNTIME_BIN_LOADER_H_
#define RUNTIME_BIN_LOADER_H_
#include "bin/isolate_data.h"
#include "bin/thread.h"
#include "include/dart_api.h"
#include "include/dart_native_api.h"
#include "platform/assert.h"
#include "platform/globals.h"
namespace dart {
namespace bin {
class Loader {
public:
explicit Loader(IsolateData* isolate_data);
~Loader();
static void InitForSnapshot(const char* snapshot_uri);
static Dart_Handle ReloadNativeExtensions();
// Loads contents of the specified url.
static Dart_Handle LoadUrlContents(Dart_Handle url,
uint8_t** payload,
intptr_t* payload_length);
static void ResolveDependenciesAsFilePaths();
// A static tag handler that hides all usage of a loader for an isolate.
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url);
Dart_Handle error() const { return error_; }
static void InitOnce();
private:
// The port assigned to our native message handler.
Dart_Port port_;
// Each Loader is associated with an Isolate via its IsolateData.
IsolateData* isolate_data_;
// Remember the first error that occurs during loading.
Dart_Handle error_;
// This monitor is used to protect the pending operations count and the
// I/O result queue.
Monitor monitor_;
// The number of operations dispatched to the service isolate for loading.
// Must be accessed with monitor_ held.
intptr_t pending_operations_;
// The result of an I/O request to the service isolate. Payload is either
// a UInt8Array or a C string containing an error message.
struct IOResult {
uint8_t* payload;
intptr_t payload_length;
char* library_uri;
char* uri;
char* resolved_uri;
int8_t tag;
void Setup(Dart_CObject* message);
void Cleanup();
};
// An array of I/O results queued from the service isolate.
IOResult* results_;
intptr_t results_length_;
intptr_t results_capacity_;
uint8_t* payload_;
intptr_t payload_length_;
typedef bool (*ProcessResult)(Loader* loader, IOResult* result);
intptr_t results_length() {
return *static_cast<volatile intptr_t*>(&results_length_);
}
// Send the loader init request to the service isolate.
void Init(const char* package_root,
const char* packages_file,
const char* working_directory,
const char* root_script_uri);
// Send a request for a dart-ext: import to the service isolate.
void SendImportExtensionRequest(Dart_Handle url, Dart_Handle library_url);
// Send a request from the tag handler to the service isolate.
void SendRequest(intptr_t tag, Dart_Handle url, Dart_Handle library_url);
static Dart_Handle SendAndProcessReply(intptr_t tag,
Dart_Handle url,
uint8_t** payload,
intptr_t* payload_length);
static Dart_Handle ResolveAsFilePath(Dart_Handle url,
uint8_t** payload,
intptr_t* payload_length);
/// Queue |message| and notify the loader that a message is available.
void QueueMessage(Dart_CObject* message);
/// Blocks the caller until the loader is finished.
void BlockUntilComplete(ProcessResult process_result);
/// Saves a script dependency when applicable.
static void AddDependencyLocked(Loader* loader, const char* resolved_uri);
/// Returns false if |result| is an error and the loader should quit.
static bool ProcessResultLocked(Loader* loader, IOResult* result);
/// Returns false if |result| is an error and the loader should quit.
static bool ProcessPayloadResultLocked(Loader* loader, IOResult* result);
/// Returns false if an error occurred and the loader should quit.
bool ProcessQueueLocked(ProcessResult process_result);
// Special inner tag handler for dart: uris.
static Dart_Handle DartColonLibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url,
const char* library_url_string,
const char* url_string);
// We use one native message handler callback for N loaders. The native
// message handler callback provides us with the Dart_Port which we use as a
// key into our map of active loaders from |port| to |isolate_data|.
// Static information to map Dart_Port back to the isolate in question.
struct LoaderInfo {
Dart_Port port;
IsolateData* isolate_data;
};
// The map of active loaders.
static Mutex* loader_infos_lock_;
static LoaderInfo* loader_infos_;
static intptr_t loader_infos_length_;
static intptr_t loader_infos_capacity_;
static void AddLoader(Dart_Port port, IsolateData* data);
static void RemoveLoader(Dart_Port port);
static intptr_t LoaderIndexFor(Dart_Port port);
static Loader* LoaderFor(Dart_Port port);
static Loader* LoaderForLocked(Dart_Port port);
// This is the global callback for the native message handlers.
static void NativeMessageHandler(Dart_Port dest_port_id,
Dart_CObject* message);
};
} // namespace bin
} // namespace dart
#endif // RUNTIME_BIN_LOADER_H_