[vm] Initial implementation of deferred loading.
(Assignment of libraries to loading units is already done in the kernel generation step.) After compiling and before serializing, we walk the program and for each Code we assign its Instructions, CodeSourceMap and CompressedStackMap to the loading unit of that Code's defining library. Deduplication may cause Instructions, CodeSourceMaps and CompressedStackMaps to belong to more than one loading unit; in this case the objects are assigned to the root loading unit. Later they can be more precisely assigned to the dominating loading unit. All objects except some Instructions, CodeSourceMaps and CompressedStackMaps belong to the root loading unit's snapshot. This snapshot is written like an unsplit snapshot, except that when serializing Code, we will write a reference to a stub or null when the Code's Instructions, CodeSourceMap or CompressedStackMap belongs to a non-root loading unit. The snapshots of non-root loading units contain these deferred objects and references to the corresponding Code objects to patch. The types of objects we defer (Instructions, CodeSourceMaps and CompressedStackMaps) usually represent 70+% of the snapshot size. Bare instructions mode must be disabled when splitting because we cannot have PC-relative calls between loading units. Later we can re-enable this for calls within loading units. Broken: Compactor probably crashes we can now have an unbounded number of image pages and the compactor assumes a fixed number. Embedder's guide: At compile-time, gen_snapshot should be passed --loading_unit_manifest with a path, which will enable splitting and output a mapping from loading unit ids to snapshot output paths. At runtime, sometime during isolate startup, an embedder should call Dart_SetDeferredLoadHandler, probably near an existing call to Dart_SetLibraryTagHandler. The callback is given a loading unit id, and should eventually call Dart_DeferredLoadComplete[Error]. Bug: https://github.com/dart-lang/sdk/issues/41974 Change-Id: Ib597eb87c8cd634416d5ee1f00629c5550aebb00 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152427 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
896f874b9f
commit
c5a94db091
@@ -3028,6 +3028,59 @@ typedef Dart_Handle (*Dart_LibraryTagHandler)(
|
||||
DART_EXPORT Dart_Handle
|
||||
Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler);
|
||||
|
||||
/**
|
||||
* Handles deferred loading requests. When this handler is invoked, it should
|
||||
* eventually load the deferred loading unit with the given id and call
|
||||
* Dart_DeferredLoadComplete or Dart_DeferredLoadCompleteError. It is
|
||||
* recommended that the loading occur asynchronously, but it is permitted to
|
||||
* call Dart_DeferredLoadComplete or Dart_DeferredLoadCompleteError before the
|
||||
* handler returns.
|
||||
*
|
||||
* If an error is returned, it will be propogated through
|
||||
* `prefix.loadLibrary()`. This is useful for synchronous
|
||||
* implementations, which must propogate any unwind errors from
|
||||
* Dart_DeferredLoadComplete or Dart_DeferredLoadComplete. Otherwise the handler
|
||||
* should return a non-error such as `Dart_Null()`.
|
||||
*/
|
||||
typedef Dart_Handle (*Dart_DeferredLoadHandler)(intptr_t loading_unit_id);
|
||||
|
||||
/**
|
||||
* Sets the deferred load handler for the current isolate. This handler is
|
||||
* used to handle loading deferred imports in an AppJIT or AppAOT program.
|
||||
*/
|
||||
DART_EXPORT Dart_Handle
|
||||
Dart_SetDeferredLoadHandler(Dart_DeferredLoadHandler handler);
|
||||
|
||||
/**
|
||||
* Notifies the VM that a deferred load completed successfully. This function
|
||||
* will eventually cause the corresponding `prefix.loadLibrary()` futures to
|
||||
* complete.
|
||||
*
|
||||
* Requires the current isolate to be the same current isolate during the
|
||||
* invocation of the Dart_DeferredLoadHandler.
|
||||
*/
|
||||
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
|
||||
Dart_DeferredLoadComplete(intptr_t loading_unit_id,
|
||||
const uint8_t* snapshot_data,
|
||||
const uint8_t* snapshot_instructions);
|
||||
|
||||
/**
|
||||
* Notifies the VM that a deferred load failed. This function
|
||||
* will eventually cause the corresponding `prefix.loadLibrary()` futures to
|
||||
* complete with an error.
|
||||
*
|
||||
* If `transient` is true, future invocations of `prefix.loadLibrary()` will
|
||||
* trigger new load requests. If false, futures invocation will complete with
|
||||
* the same error.
|
||||
*
|
||||
* Requires the current isolate to be the same current isolate during the
|
||||
* invocation of the Dart_DeferredLoadHandler.
|
||||
*/
|
||||
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
|
||||
Dart_DeferredLoadCompleteError(intptr_t loading_unit_id,
|
||||
const char* error_message,
|
||||
bool transient);
|
||||
|
||||
/**
|
||||
* Canonicalizes a url with respect to some library.
|
||||
*
|
||||
@@ -3522,9 +3575,15 @@ Dart_LoadTypeFeedback(uint8_t* buffer, intptr_t buffer_length);
|
||||
*/
|
||||
DART_EXPORT Dart_Handle Dart_Precompile();
|
||||
|
||||
typedef void (*Dart_CreateLoadingUnitCallback)(
|
||||
void* callback_data,
|
||||
intptr_t loading_unit_id,
|
||||
void** write_callback_data,
|
||||
void** write_debug_callback_data);
|
||||
typedef void (*Dart_StreamingWriteCallback)(void* callback_data,
|
||||
const uint8_t* buffer,
|
||||
intptr_t size);
|
||||
typedef void (*Dart_StreamingCloseCallback)(void* callback_data);
|
||||
|
||||
// On Darwin systems, 'dlsym' adds an '_' to the beginning of the symbol name.
|
||||
// Use the '...CSymbol' definitions for resolving through 'dlsym'. The actual
|
||||
@@ -3580,6 +3639,13 @@ Dart_CreateAppAOTSnapshotAsAssembly(Dart_StreamingWriteCallback callback,
|
||||
void* callback_data,
|
||||
bool stripped,
|
||||
void* debug_callback_data);
|
||||
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
|
||||
Dart_CreateAppAOTSnapshotAsAssemblies(
|
||||
Dart_CreateLoadingUnitCallback next_callback,
|
||||
void* next_callback_data,
|
||||
bool stripped,
|
||||
Dart_StreamingWriteCallback write_callback,
|
||||
Dart_StreamingCloseCallback close_callback);
|
||||
|
||||
/**
|
||||
* Creates a precompiled snapshot.
|
||||
@@ -3613,6 +3679,12 @@ Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback,
|
||||
void* callback_data,
|
||||
bool stripped,
|
||||
void* debug_callback_data);
|
||||
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
|
||||
Dart_CreateAppAOTSnapshotAsElfs(Dart_CreateLoadingUnitCallback next_callback,
|
||||
void* next_callback_data,
|
||||
bool stripped,
|
||||
Dart_StreamingWriteCallback write_callback,
|
||||
Dart_StreamingCloseCallback close_callback);
|
||||
|
||||
/**
|
||||
* Like Dart_CreateAppAOTSnapshotAsAssembly, but only includes
|
||||
|
||||
Reference in New Issue
Block a user