mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 14:11:18 +00:00
Changes to make isolate reload functionality work with the --dfe option.
R=aam@google.com, rmacnak@google.com Review-Url: https://codereview.chromium.org/2894773004 .
This commit is contained in:
parent
a865f0ecf2
commit
286dd51948
|
@ -293,6 +293,8 @@ executable("gen_snapshot") {
|
|||
# Very limited native resolver provided.
|
||||
"builtin_common.cc",
|
||||
"builtin_gen_snapshot.cc",
|
||||
"dfe.cc",
|
||||
"dfe.h",
|
||||
"gen_snapshot.cc",
|
||||
"vmservice_impl.cc",
|
||||
"vmservice_impl.h",
|
||||
|
@ -669,6 +671,8 @@ dart_executable("dart") {
|
|||
]
|
||||
extra_sources = [
|
||||
"builtin_nolib.cc",
|
||||
"dfe.cc",
|
||||
"dfe.h",
|
||||
"loader.cc",
|
||||
"loader.h",
|
||||
]
|
||||
|
@ -715,6 +719,8 @@ dart_executable("dart_bootstrap") {
|
|||
extra_sources = [
|
||||
"builtin.cc",
|
||||
"builtin.h",
|
||||
"dfe.cc",
|
||||
"dfe.h",
|
||||
"loader.cc",
|
||||
"loader.h",
|
||||
"observatory_assets_empty.cc",
|
||||
|
@ -857,6 +863,8 @@ executable("run_vm_tests") {
|
|||
"snapshot_utils.h",
|
||||
"builtin_nolib.cc",
|
||||
"run_vm_tests.cc",
|
||||
"dfe.cc",
|
||||
"dfe.h",
|
||||
] + builtin_impl_tests_list + vm_tests
|
||||
|
||||
if (!is_win) {
|
||||
|
|
|
@ -953,6 +953,8 @@
|
|||
'builtin_common.cc',
|
||||
'builtin.cc',
|
||||
'builtin.h',
|
||||
'dfe.cc',
|
||||
'dfe.h',
|
||||
'loader.cc',
|
||||
'loader.h',
|
||||
'platform_android.cc',
|
||||
|
@ -1129,12 +1131,14 @@
|
|||
'builtin_common.cc',
|
||||
'builtin_natives.cc',
|
||||
'builtin_nolib.cc',
|
||||
'dfe.cc',
|
||||
'dfe.h',
|
||||
'error_exit.cc',
|
||||
'error_exit.h',
|
||||
'io_natives.h',
|
||||
'main.cc',
|
||||
'loader.cc',
|
||||
'loader.h',
|
||||
'main.cc',
|
||||
'snapshot_utils.cc',
|
||||
'snapshot_utils.h',
|
||||
'vmservice_impl.cc',
|
||||
|
@ -1246,12 +1250,14 @@
|
|||
'builtin.h',
|
||||
'builtin_common.cc',
|
||||
'builtin_natives.cc',
|
||||
'dfe.cc',
|
||||
'dfe.h',
|
||||
'error_exit.cc',
|
||||
'error_exit.h',
|
||||
'io_natives.h',
|
||||
'main.cc',
|
||||
'loader.cc',
|
||||
'loader.h',
|
||||
'main.cc',
|
||||
'observatory_assets_empty.cc',
|
||||
'snapshot_empty.cc',
|
||||
'snapshot_utils.cc',
|
||||
|
@ -1334,6 +1340,8 @@
|
|||
'builtin_natives.cc',
|
||||
'builtin_nolib.cc',
|
||||
'builtin.h',
|
||||
'dfe.cc',
|
||||
'dfe.h',
|
||||
'io_natives.h',
|
||||
'loader.cc',
|
||||
'loader.h',
|
||||
|
|
|
@ -60,39 +60,6 @@ MagicNumberData snapshot_magic_number = {{0xf5, 0xf5, 0xdc, 0xdc}, true};
|
|||
MagicNumberData kernel_magic_number = {{0x90, 0xab, 0xcd, 0xef}, false};
|
||||
|
||||
|
||||
bool TryReadKernel(const char* script_uri,
|
||||
const uint8_t** kernel_file,
|
||||
intptr_t* kernel_length) {
|
||||
*kernel_file = NULL;
|
||||
*kernel_length = -1;
|
||||
bool is_kernel_file = false;
|
||||
void* script_file = DartUtils::OpenFile(script_uri, false);
|
||||
if (script_file != NULL) {
|
||||
const uint8_t* buffer = NULL;
|
||||
DartUtils::ReadFile(&buffer, kernel_length, script_file);
|
||||
DartUtils::CloseFile(script_file);
|
||||
if (*kernel_length > 0 && buffer != NULL) {
|
||||
// We need a temporary variable because SniffForMagicNumber modifies the
|
||||
// buffer pointer to skip snapshot magic number.
|
||||
const uint8_t* temp = buffer;
|
||||
if (DartUtils::SniffForMagicNumber(&temp, kernel_length) !=
|
||||
DartUtils::kKernelMagicNumber) {
|
||||
free(const_cast<uint8_t*>(buffer));
|
||||
*kernel_file = NULL;
|
||||
} else {
|
||||
// Do not free buffer if this is a kernel file - kernel_file will be
|
||||
// backed by the same memory as the buffer and caller will own it.
|
||||
// Caller is responsible for freeing the buffer when this function
|
||||
// returns true.
|
||||
is_kernel_file = true;
|
||||
*kernel_file = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_kernel_file;
|
||||
}
|
||||
|
||||
|
||||
static bool IsWindowsHost() {
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
return true;
|
||||
|
|
|
@ -33,14 +33,6 @@ static inline Dart_Handle ThrowIfError(Dart_Handle handle) {
|
|||
return handle;
|
||||
}
|
||||
|
||||
// Tries to read [script_uri] as a Kernel IR file. If successful this function
|
||||
// returns `true` and sets [kernel_file] and [kernel_length] to be the memory
|
||||
// contents.
|
||||
//
|
||||
// The caller is responsible for free()ing [kernel_file] if `true` was returned.
|
||||
bool TryReadKernel(const char* script_uri,
|
||||
const uint8_t** kernel_file,
|
||||
intptr_t* kernel_length);
|
||||
|
||||
class CommandLineOptions {
|
||||
public:
|
||||
|
|
93
runtime/bin/dfe.cc
Normal file
93
runtime/bin/dfe.cc
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Copyright (c) 2017, 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 "bin/dfe.h"
|
||||
#include "bin/dartutils.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
DFE::DFE() : frontend_filename_(NULL), platform_binary_filename_(NULL) {}
|
||||
|
||||
|
||||
DFE::~DFE() {
|
||||
frontend_filename_ = NULL;
|
||||
platform_binary_filename_ = NULL;
|
||||
}
|
||||
|
||||
Dart_Handle DFE::ReloadScript(Dart_Isolate isolate, Dart_Handle url) {
|
||||
ASSERT(!Dart_IsServiceIsolate(isolate) && !Dart_IsKernelIsolate(isolate));
|
||||
const char* url_string = NULL;
|
||||
Dart_Handle result = Dart_StringToCString(url, &url_string);
|
||||
if (Dart_IsError(result)) {
|
||||
return result;
|
||||
}
|
||||
// First check if the URL points to a Kernel IR file in which case we
|
||||
// skip the compilation step and directly reload the file.
|
||||
const uint8_t* kernel_ir = NULL;
|
||||
intptr_t kernel_ir_size = -1;
|
||||
if (!TryReadKernelFile(url_string, &kernel_ir, &kernel_ir_size)) {
|
||||
// We have a source file, compile it into a kernel ir first.
|
||||
// TODO(asiva): We will have to change this API to pass in a list of files
|
||||
// that have changed. For now just pass in the main url_string and have it
|
||||
// recompile the script.
|
||||
Dart_KernelCompilationResult kresult = Dart_CompileToKernel(url_string);
|
||||
if (kresult.status != Dart_KernelCompilationStatus_Ok) {
|
||||
return Dart_NewApiError(kresult.error);
|
||||
}
|
||||
kernel_ir = kresult.kernel;
|
||||
kernel_ir_size = kresult.kernel_size;
|
||||
}
|
||||
void* kernel_program = Dart_ReadKernelBinary(kernel_ir, kernel_ir_size);
|
||||
ASSERT(kernel_program != NULL);
|
||||
result = Dart_LoadKernel(kernel_program);
|
||||
if (Dart_IsError(result)) {
|
||||
return result;
|
||||
}
|
||||
// Finalize loading. This will complete any futures for completed deferred
|
||||
// loads.
|
||||
result = Dart_FinalizeLoading(true);
|
||||
if (Dart_IsError(result)) {
|
||||
return result;
|
||||
}
|
||||
return Dart_Null();
|
||||
}
|
||||
|
||||
|
||||
bool DFE::TryReadKernelFile(const char* script_uri,
|
||||
const uint8_t** kernel_ir,
|
||||
intptr_t* kernel_ir_size) {
|
||||
*kernel_ir = NULL;
|
||||
*kernel_ir_size = -1;
|
||||
void* script_file = DartUtils::OpenFile(script_uri, false);
|
||||
if (script_file != NULL) {
|
||||
const uint8_t* buffer = NULL;
|
||||
DartUtils::ReadFile(&buffer, kernel_ir_size, script_file);
|
||||
DartUtils::CloseFile(script_file);
|
||||
if (*kernel_ir_size > 0 && buffer != NULL) {
|
||||
// We need a temporary variable because SniffForMagicNumber modifies the
|
||||
// buffer pointer to skip snapshot magic number.
|
||||
const uint8_t* temp = buffer;
|
||||
if (DartUtils::SniffForMagicNumber(&temp, kernel_ir_size) !=
|
||||
DartUtils::kKernelMagicNumber) {
|
||||
free(const_cast<uint8_t*>(buffer));
|
||||
*kernel_ir = NULL;
|
||||
*kernel_ir_size = -1;
|
||||
return false;
|
||||
} else {
|
||||
// Do not free buffer if this is a kernel file - kernel_file will be
|
||||
// backed by the same memory as the buffer and caller will own it.
|
||||
// Caller is responsible for freeing the buffer when this function
|
||||
// returns true.
|
||||
*kernel_ir = buffer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
58
runtime/bin/dfe.h
Normal file
58
runtime/bin/dfe.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2017, 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_DFE_H_
|
||||
#define RUNTIME_BIN_DFE_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 DFE {
|
||||
public:
|
||||
DFE();
|
||||
~DFE();
|
||||
|
||||
const char* frontend_filename() const { return frontend_filename_; }
|
||||
void set_frontend_filename(const char* name) { frontend_filename_ = name; }
|
||||
bool UseDartFrontend() const { return frontend_filename_ != NULL; }
|
||||
|
||||
const char* platform_binary_filename() const {
|
||||
return platform_binary_filename_;
|
||||
}
|
||||
void set_platform_binary_filename(const char* name) {
|
||||
platform_binary_filename_ = name;
|
||||
}
|
||||
bool UsePlatformBinary() const { return platform_binary_filename_ != NULL; }
|
||||
|
||||
// Method to reload a script into a running a isolate.
|
||||
// If the specified script [url] is not a kernel IR, compile it first using
|
||||
// DFE and then reload the resulting kernel IR into the isolate.
|
||||
// Returns Dart_Null if successful, otherwise an error object is returned.
|
||||
Dart_Handle ReloadScript(Dart_Isolate isolate, Dart_Handle url);
|
||||
|
||||
// Tries to read [script_uri] as a Kernel IR file.
|
||||
// Returns `true` if successful and sets [kernel_file] and [kernel_length]
|
||||
// to be the kernel IR contents.
|
||||
// The caller is responsible for free()ing [kernel_file] if `true`
|
||||
// was returned.
|
||||
bool TryReadKernelFile(const char* script_uri,
|
||||
const uint8_t** kernel_ir,
|
||||
intptr_t* kernel_ir_size);
|
||||
|
||||
private:
|
||||
const char* frontend_filename_;
|
||||
const char* platform_binary_filename_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DFE);
|
||||
};
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_BIN_DFE_H_
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/eventhandler.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/loader.h"
|
||||
|
@ -31,6 +32,8 @@
|
|||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
DFE dfe;
|
||||
|
||||
// Exit code indicating an API error.
|
||||
static const int kApiErrorExitCode = 253;
|
||||
// Exit code indicating a compilation error.
|
||||
|
@ -1570,7 +1573,7 @@ int main(int argc, char** argv) {
|
|||
const uint8_t* kernel = NULL;
|
||||
intptr_t kernel_length = 0;
|
||||
const bool is_kernel_file =
|
||||
TryReadKernel(app_script_name, &kernel, &kernel_length);
|
||||
dfe.TryReadKernelFile(app_script_name, &kernel, &kernel_length);
|
||||
|
||||
if ((dependencies_filename != NULL) || print_dependencies) {
|
||||
isolate_data->set_dependencies(new MallocGrowableArray<char*>());
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/extensions.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/lockers.h"
|
||||
|
@ -19,6 +20,10 @@ namespace bin {
|
|||
|
||||
// Development flag.
|
||||
static bool trace_loader = false;
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
extern DFE dfe;
|
||||
#endif
|
||||
|
||||
// Keep in sync with loader.dart.
|
||||
static const intptr_t _Dart_kImportExtension = 9;
|
||||
static const intptr_t _Dart_kResolveAsFilePath = 10;
|
||||
|
@ -638,6 +643,19 @@ Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag,
|
|||
Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
|
||||
Dart_Handle library,
|
||||
Dart_Handle url) {
|
||||
if (dfe.UseDartFrontend()) {
|
||||
Dart_Isolate current = Dart_CurrentIsolate();
|
||||
if (!Dart_IsServiceIsolate(current) && !Dart_IsKernelIsolate(current)) {
|
||||
// When using DFE the library tag handler should be called only when we
|
||||
// are reloading scripts.
|
||||
// TODO(asiva) We need to ensure that the kernel and service isolates
|
||||
// and the spawnURI paths are always loaded from a kernel IR and do
|
||||
// not use this path.
|
||||
if (tag == Dart_kScriptTag) {
|
||||
return dfe.ReloadScript(current, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tag == Dart_kCanonicalizeUrl) {
|
||||
Dart_Handle library_url = Dart_LibraryUrl(library);
|
||||
if (Dart_IsError(library_url)) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/directory.h"
|
||||
#include "bin/embedded_dart_io.h"
|
||||
#include "bin/error_exit.h"
|
||||
|
@ -78,15 +79,9 @@ enum SnapshotKind {
|
|||
};
|
||||
static SnapshotKind gen_snapshot_kind = kNone;
|
||||
static const char* snapshot_deps_filename = NULL;
|
||||
|
||||
static bool use_dart_frontend = false;
|
||||
|
||||
static const char* frontend_filename = NULL;
|
||||
|
||||
// True if the VM should boostrap the SDK from a binary (.dill) file. The
|
||||
// filename points into an argv buffer and does not need to be freed.
|
||||
static bool use_platform_binary = false;
|
||||
static const char* platform_binary_filename = NULL;
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
DFE dfe;
|
||||
#endif
|
||||
|
||||
// Value of the --save-feedback flag.
|
||||
// (This pointer points into an argv buffer and does not need to be
|
||||
|
@ -340,14 +335,14 @@ static bool ProcessParseAllOption(const char* arg,
|
|||
}
|
||||
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
static bool ProcessFrontendOption(const char* filename,
|
||||
CommandLineOptions* vm_options) {
|
||||
ASSERT(filename != NULL);
|
||||
if (filename[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
use_dart_frontend = true;
|
||||
frontend_filename = filename;
|
||||
dfe.set_frontend_filename(filename);
|
||||
vm_options->AddArgument("--use-dart-frontend");
|
||||
return true;
|
||||
}
|
||||
|
@ -359,10 +354,10 @@ static bool ProcessPlatformOption(const char* filename,
|
|||
if (filename[0] == '\0') {
|
||||
return false;
|
||||
}
|
||||
use_platform_binary = true;
|
||||
platform_binary_filename = filename;
|
||||
dfe.set_platform_binary_filename(filename);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static bool ProcessUseBlobsOption(const char* arg,
|
||||
|
@ -588,8 +583,10 @@ static struct {
|
|||
// VM specific options to the standalone dart program.
|
||||
{"--compile_all", ProcessCompileAllOption},
|
||||
{"--parse_all", ProcessParseAllOption},
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
{"--dfe=", ProcessFrontendOption},
|
||||
{"--platform=", ProcessPlatformOption},
|
||||
#endif
|
||||
{"--enable-vm-service", ProcessEnableVmServiceOption},
|
||||
{"--disable-service-origin-check", ProcessDisableServiceOriginCheckOption},
|
||||
{"--observe", ProcessObserveOption},
|
||||
|
@ -837,19 +834,6 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
|
|||
char** error,
|
||||
int* exit_code) {
|
||||
ASSERT(script_uri != NULL);
|
||||
const bool is_kernel_isolate =
|
||||
strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0;
|
||||
if (is_kernel_isolate) {
|
||||
if (!use_dart_frontend) {
|
||||
*error = strdup("Kernel isolate not supported.");
|
||||
return NULL;
|
||||
}
|
||||
script_uri = frontend_filename;
|
||||
if (packages_config == NULL) {
|
||||
packages_config = commandline_packages_file;
|
||||
}
|
||||
}
|
||||
|
||||
void* kernel_platform = NULL;
|
||||
void* kernel_program = NULL;
|
||||
AppSnapshot* app_snapshot = NULL;
|
||||
|
@ -867,6 +851,18 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
|
|||
const uint8_t* isolate_snapshot_data = core_isolate_snapshot_data;
|
||||
const uint8_t* isolate_snapshot_instructions =
|
||||
core_isolate_snapshot_instructions;
|
||||
const bool is_kernel_isolate =
|
||||
strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0;
|
||||
if (is_kernel_isolate) {
|
||||
if (!dfe.UseDartFrontend()) {
|
||||
*error = strdup("Kernel isolate not supported.");
|
||||
return NULL;
|
||||
}
|
||||
script_uri = dfe.frontend_filename();
|
||||
if (packages_config == NULL) {
|
||||
packages_config = commandline_packages_file;
|
||||
}
|
||||
}
|
||||
if ((app_isolate_snapshot_data != NULL) &&
|
||||
(is_main_isolate || ((app_script_uri != NULL) &&
|
||||
(strcmp(script_uri, app_script_uri) == 0)))) {
|
||||
|
@ -888,10 +884,10 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
|
|||
strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0;
|
||||
if (!is_kernel_isolate && !is_service_isolate) {
|
||||
const uint8_t* platform_file = NULL;
|
||||
if (use_platform_binary) {
|
||||
if (dfe.UsePlatformBinary()) {
|
||||
intptr_t platform_length = -1;
|
||||
bool success = TryReadKernel(platform_binary_filename, &platform_file,
|
||||
&platform_length);
|
||||
bool success = dfe.TryReadKernelFile(dfe.platform_binary_filename(),
|
||||
&platform_file, &platform_length);
|
||||
if (!success) {
|
||||
*error = strdup("The platform binary is not a valid Dart Kernel file.");
|
||||
*exit_code = kErrorExitCode;
|
||||
|
@ -903,7 +899,7 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
|
|||
bool is_kernel = false;
|
||||
const uint8_t* kernel_file = NULL;
|
||||
intptr_t kernel_length = -1;
|
||||
if (use_dart_frontend) {
|
||||
if (dfe.UseDartFrontend()) {
|
||||
Dart_KernelCompilationResult result = Dart_CompileToKernel(script_uri);
|
||||
*error = result.error; // Copy error message (if any).
|
||||
switch (result.status) {
|
||||
|
@ -928,7 +924,8 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
|
|||
return NULL;
|
||||
}
|
||||
} else if (!isolate_run_app_snapshot) {
|
||||
is_kernel = TryReadKernel(script_uri, &kernel_file, &kernel_length);
|
||||
is_kernel =
|
||||
dfe.TryReadKernelFile(script_uri, &kernel_file, &kernel_length);
|
||||
}
|
||||
|
||||
if (is_kernel) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/dfe.h"
|
||||
#include "bin/file.h"
|
||||
#include "bin/loader.h"
|
||||
#include "bin/platform.h"
|
||||
|
@ -24,6 +25,10 @@ extern const uint8_t kDartCoreIsolateSnapshotInstructions[];
|
|||
// TODO(iposva, asiva): This is a placeholder for the real unittest framework.
|
||||
namespace dart {
|
||||
|
||||
namespace bin {
|
||||
DFE dfe;
|
||||
}
|
||||
|
||||
// Defined in vm/os_thread_win.cc
|
||||
extern bool private_flag_windows_run_tls_destructors;
|
||||
|
||||
|
|
Loading…
Reference in a new issue