New dart CLI option to create a snapshot depfile. (#29165)

This commit is contained in:
P.Y. Laligand 2017-03-27 06:44:21 -07:00 committed by John McCutchan
parent 02573b3caa
commit 8f03520d2b
3 changed files with 74 additions and 2 deletions

View file

@ -12,6 +12,7 @@
#include "bin/lockers.h"
#include "bin/utils.h"
#include "include/dart_tools_api.h"
#include "platform/growable_array.h"
namespace dart {
namespace bin {
@ -283,6 +284,28 @@ static bool PathContainsSeparator(const char* path) {
}
void Loader::AddDependencyLocked(Loader* loader, const char* resolved_uri) {
MallocGrowableArray<char*>* dependencies =
loader->isolate_data_->dependencies();
if (dependencies == NULL) {
return;
}
uint8_t* scoped_file_path = NULL;
intptr_t scoped_file_path_length = -1;
Dart_Handle uri = Dart_NewStringFromCString(resolved_uri);
ASSERT(!Dart_IsError(uri));
Dart_Handle result = Loader::ResolveAsFilePath(uri, &scoped_file_path,
&scoped_file_path_length);
if (Dart_IsError(result)) {
Log::Print("Error resolving dependency: %s\n", Dart_GetError(result));
return;
}
dependencies->Add(StringUtils::StrNDup(
reinterpret_cast<const char*>(scoped_file_path),
scoped_file_path_length));
}
bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) {
// We have to copy everything we care about out of |result| because after
// dropping the lock below |result| may no longer valid.
@ -296,6 +319,8 @@ bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) {
Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri));
}
AddDependencyLocked(loader, result->resolved_uri);
// A negative result tag indicates a loading error occurred in the service
// isolate. The payload is a C string of the error message.
if (result->tag < 0) {

View file

@ -108,6 +108,9 @@ class Loader {
/// 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);

View file

@ -27,6 +27,7 @@
#include "bin/utils.h"
#include "bin/vmservice_impl.h"
#include "platform/globals.h"
#include "platform/growable_array.h"
#include "platform/hashmap.h"
#include "platform/text_buffer.h"
#if !defined(DART_PRECOMPILER)
@ -60,6 +61,7 @@ enum SnapshotKind {
kAppJIT,
};
static SnapshotKind gen_snapshot_kind = kNone;
static const char* snapshot_deps_filename = NULL;
static bool use_dart_frontend = false;
@ -372,6 +374,13 @@ static bool ProcessSnapshotKindOption(const char* kind,
}
static bool ProcessSnapshotDepsFilenameOption(const char* filename,
CommandLineOptions* vm_options) {
snapshot_deps_filename = filename;
return true;
}
static bool ProcessEnableVmServiceOption(const char* option_value,
CommandLineOptions* vm_options) {
ASSERT(option_value != NULL);
@ -553,6 +562,7 @@ static struct {
{"--observe", ProcessObserveOption},
{"--snapshot=", ProcessSnapshotFilenameOption},
{"--snapshot-kind=", ProcessSnapshotKindOption},
{"--snapshot-depfile=", ProcessSnapshotDepsFilenameOption},
{"--use-blobs", ProcessUseBlobsOption},
{"--save-feedback=", ProcessSaveFeedbackOption},
{"--load-feedback=", ProcessLoadFeedbackOption},
@ -688,7 +698,8 @@ static int ParseArguments(int argc,
Log::PrintErr("Empty package file name specified.\n");
return -1;
}
if ((gen_snapshot_kind != kNone) && (snapshot_filename == NULL)) {
if (((gen_snapshot_kind != kNone) || (snapshot_deps_filename != NULL)) &&
(snapshot_filename == NULL)) {
Log::PrintErr("Generating a snapshot requires a filename (--snapshot).\n");
return -1;
}
@ -783,7 +794,6 @@ static void SnapshotOnExitHook(int64_t exit_code) {
}
}
// Returns newly created Isolate on success, NULL on failure.
static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
const char* script_uri,
@ -880,6 +890,9 @@ static Dart_Isolate CreateIsolateAndSetupHelper(bool is_main_isolate,
IsolateData* isolate_data =
new IsolateData(script_uri, package_root, packages_config, app_snapshot);
if (is_main_isolate && (snapshot_deps_filename != NULL)) {
isolate_data->set_dependencies(new MallocGrowableArray<char*>());
}
// If the script is a Kernel binary, then we will try to bootstrap from the
// script.
Dart_Isolate isolate =
@ -1419,7 +1432,38 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) {
}
}
if (snapshot_deps_filename != NULL) {
IsolateData* isolate_data =
reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
ASSERT(isolate_data != NULL);
MallocGrowableArray<char*>* dependencies = isolate_data->dependencies();
ASSERT(dependencies != NULL);
File* file = File::Open(snapshot_deps_filename, File::kWriteTruncate);
if (file == NULL) {
ErrorExit(kErrorExitCode,
"Error: Unable to open snapshot depfile: %s\n\n",
snapshot_deps_filename);
}
bool success = true;
success &= file->Print("%s: ", snapshot_filename);
for (intptr_t i = 0; i < dependencies->length(); i++) {
char* dep = dependencies->At(i);
success &= file->Print("%s ", dep);
free(dep);
}
success &= file->Print("\n");
if (!success) {
ErrorExit(kErrorExitCode,
"Error: Unable to write snapshot depfile: %s\n\n",
snapshot_deps_filename);
}
file->Release();
isolate_data->set_dependencies(NULL);
delete dependencies;
}
Dart_ExitScope();
// Shutdown the isolate.
Dart_ShutdownIsolate();