Skip to content

Commit 08252fc

Browse files
a-sivaCommit Queue
authored and
Commit Queue
committed
[dartdev] Use VmInteropHandler for invoking sub commands
Use VmInteropHandler for invoking sub commands instead of running them in an isolate. Running sub commands in an isolate causes an increased footprint. Changing this to use VmInteropHandler avoids the additional memory footprint. Commands that need to use an AOT runtime for execution now exec the AOT runtime and run the command. TEST=ci Change-Id: If7aed1cab2fec9d9940bd562ad5aa9c4e9a6ac7f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398604 Reviewed-by: Ben Konyi <[email protected]> Reviewed-by: Brian Quinlan <[email protected]> Commit-Queue: Siva Annamalai <[email protected]>
1 parent 96c4e4c commit 08252fc

11 files changed

+362
-55
lines changed

pkg/dartdev/lib/src/commands/compile.dart

+11-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import '../experiments.dart';
1717
import '../native_assets.dart';
1818
import '../sdk.dart';
1919
import '../utils.dart';
20+
import '../vm_interop_handler.dart';
2021

2122
const int genericErrorExitCode = 255;
2223
const int compileErrorExitCode = 254;
@@ -93,17 +94,18 @@ class CompileJSCommand extends CompileSubcommandCommand {
9394
final args = argResults!;
9495
var snapshot = sdk.dart2jsAotSnapshot;
9596
var runtime = sdk.dartAotRuntime;
97+
var isAOT = true;
9698
if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
9799
// AOT snapshots cannot be generated on IA32, so we need this fallback
98100
// branch until support for IA32 is dropped (https://dartbug.com/49969).
99101
snapshot = sdk.dart2jsSnapshot;
100-
runtime = sdk.dart;
101102
if (!Sdk.checkArtifactExists(snapshot)) {
102103
return genericErrorExitCode;
103104
}
105+
runtime = sdk.dart;
106+
isAOT = false;
104107
}
105108
final dart2jsCommand = [
106-
runtime,
107109
snapshot,
108110
'--libraries-spec=${sdk.librariesJson}',
109111
'--cfe-invocation-modes=compile',
@@ -112,8 +114,13 @@ class CompileJSCommand extends CompileSubcommandCommand {
112114
if (args.rest.isNotEmpty) ...args.rest.sublist(0),
113115
];
114116
try {
115-
final exitCode = await runProcessInheritStdio(dart2jsCommand);
116-
return exitCode;
117+
VmInteropHandler.run(
118+
runtime,
119+
dart2jsCommand,
120+
packageConfigOverride: null,
121+
isAOT : isAOT,
122+
);
123+
return 0;
117124
} catch (e, st) {
118125
log.stderr('Error: JS compilation failed');
119126
log.stderr(e.toString());

pkg/dartdev/lib/src/vm_interop_handler.dart

+8-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ abstract class VmInteropHandler {
1818
///
1919
/// If [markMainIsolateAsSystemIsolate] is given and set to true, the spawned
2020
/// isolate will run with `--mark-main-isolate-as-system-isolate` enabled.
21+
///
22+
/// If [isAOT] is given and set to true, the script is executed by
23+
/// execing the dartaotruntime.
2124
static void run(
2225
String script,
2326
List<String> args, {
@@ -27,11 +30,12 @@ abstract class VmInteropHandler {
2730
//
2831
// See https://github.com/dart-lang/sdk/issues/53576
2932
bool markMainIsolateAsSystemIsolate = false,
33+
bool isAOT = false,
3034
}) {
3135
final port = _port;
3236
if (port == null) return;
3337
final message = <dynamic>[
34-
_kResultRun,
38+
isAOT ? _kResultRunAOT : _kResultRunJIT,
3539
script,
3640
packageConfigOverride,
3741
markMainIsolateAsSystemIsolate,
@@ -51,8 +55,9 @@ abstract class VmInteropHandler {
5155
}
5256

5357
// Note: keep in sync with runtime/bin/dartdev_isolate.h
54-
static const int _kResultRun = 1;
55-
static const int _kResultExit = 2;
58+
static const int _kResultRunJIT = 1;
59+
static const int _kResultRunAOT = 2;
60+
static const int _kResultExit = 3;
5661

5762
static SendPort? _port;
5863
}

runtime/bin/dartdev_isolate.cc

+86-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ DartDevIsolate::DartDevRunner DartDevIsolate::runner_ =
3838
DartDevIsolate::DartDevRunner();
3939
bool DartDevIsolate::should_run_dart_dev_ = false;
4040
bool DartDevIsolate::print_usage_error_ = false;
41+
CommandLineOptions* DartDevIsolate::vm_options_ = nullptr;
4142
Monitor* DartDevIsolate::DartDevRunner::monitor_ = new Monitor();
4243
DartDevIsolate::DartDev_Result DartDevIsolate::DartDevRunner::result_ =
4344
DartDevIsolate::DartDev_Result_Unknown;
@@ -138,7 +139,7 @@ void DartDevIsolate::DartDevRunner::Run(
138139
Thread::Start("DartDev Runner", RunCallback, reinterpret_cast<uword>(this));
139140
monitor_->WaitMicros(Monitor::kNoTimeout);
140141

141-
if (result_ == DartDevIsolate::DartDev_Result_Run) {
142+
if (result_ == DartDevIsolate::DartDev_Result_RunJIT) {
142143
// Clear the DartDev dart_options and replace them with the processed
143144
// options provided by DartDev.
144145
dart_options_->Reset();
@@ -157,8 +158,8 @@ void DartDevIsolate::DartDevRunner::DartDevResultCallback(
157158
ASSERT(message->type == Dart_CObject_kArray);
158159
int32_t type = GetArrayItem(message, 0)->value.as_int32;
159160
switch (type) {
160-
case DartDevIsolate::DartDev_Result_Run: {
161-
result_ = DartDevIsolate::DartDev_Result_Run;
161+
case DartDevIsolate::DartDev_Result_RunJIT: {
162+
result_ = DartDevIsolate::DartDev_Result_RunJIT;
162163
ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
163164
auto item2 = GetArrayItem(message, 2);
164165

@@ -204,6 +205,86 @@ void DartDevIsolate::DartDevRunner::DartDevResultCallback(
204205
}
205206
break;
206207
}
208+
case DartDevIsolate::DartDev_Result_RunAOT: {
209+
result_ = DartDevIsolate::DartDev_Result_RunAOT;
210+
ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
211+
auto item2 = GetArrayItem(message, 2);
212+
213+
ASSERT(item2->type == Dart_CObject_kString ||
214+
item2->type == Dart_CObject_kNull);
215+
216+
auto item3 = GetArrayItem(message, 3);
217+
218+
ASSERT(item3->type == Dart_CObject_kBool);
219+
const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
220+
if (mark_main_isolate_as_system_isolate) {
221+
Options::set_mark_main_isolate_as_system_isolate(true);
222+
}
223+
224+
if (*script_ != nullptr) {
225+
free(*script_);
226+
}
227+
if (*package_config_override_ != nullptr) {
228+
free(*package_config_override_);
229+
*package_config_override_ = nullptr;
230+
}
231+
*script_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
232+
233+
if (item2->type == Dart_CObject_kString) {
234+
*package_config_override_ = Utils::StrDup(item2->value.as_string);
235+
}
236+
237+
intptr_t num_vm_options = 0;
238+
const char** vm_options = nullptr;
239+
ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
240+
Dart_CObject* args = GetArrayItem(message, 4);
241+
intptr_t argc = args->value.as_array.length;
242+
Dart_CObject** dart_args = args->value.as_array.values;
243+
244+
if (vm_options_ != nullptr) {
245+
num_vm_options = vm_options_->count();
246+
vm_options = vm_options_->arguments();
247+
}
248+
auto deleter = [](char** args) {
249+
for (intptr_t i = 0; i < argc_; ++i) {
250+
free(args[i]);
251+
}
252+
delete[] args;
253+
};
254+
// Total count of arguments to be passed to the script being execed.
255+
argc_ = argc + num_vm_options + 1;
256+
257+
// Array of arguments to be passed to the script being execed.
258+
argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
259+
deleter);
260+
261+
intptr_t idx = 0;
262+
// Copy in name of the script to run (dartaotruntime).
263+
argv_[0] = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
264+
idx += 1;
265+
// Copy in any vm options that need to be passed to the execed process.
266+
for (intptr_t i = 0; i < num_vm_options; ++i) {
267+
argv_[i + idx] = Utils::StrDup(vm_options[i]);
268+
}
269+
idx += num_vm_options;
270+
// Copy in the dart options that need to be passed to the command.
271+
for (intptr_t i = 0; i < argc; ++i) {
272+
argv_[i + idx] = Utils::StrDup(dart_args[i]->value.as_string);
273+
}
274+
// Null terminate the argv array.
275+
argv_[argc + idx] = nullptr;
276+
277+
// Exec the script to be run and pass the arguments.
278+
char err_msg[256];
279+
err_msg[0] = '\0';
280+
int ret = Process::Exec(nullptr, *script_,
281+
const_cast<const char**>(argv_.get()), argc_,
282+
nullptr, err_msg, sizeof(err_msg));
283+
if (ret != 0) {
284+
ProcessError(err_msg, kErrorExitCode);
285+
}
286+
break;
287+
}
207288
case DartDevIsolate::DartDev_Result_Exit: {
208289
ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kInt32);
209290
int32_t dartdev_exit_code = GetArrayItem(message, 1)->value.as_int32;
@@ -314,7 +395,9 @@ DartDevIsolate::DartDev_Result DartDevIsolate::RunDartDev(
314395
Dart_IsolateGroupCreateCallback create_isolate,
315396
char** packages_file,
316397
char** script,
398+
CommandLineOptions* vm_options,
317399
CommandLineOptions* dart_options) {
400+
vm_options_ = vm_options;
318401
runner_.Run(create_isolate, packages_file, script, dart_options);
319402
return runner_.result();
320403
}

runtime/bin/dartdev_isolate.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ class DartDevIsolate {
2727
// Note: keep in sync with pkg/dartdev/lib/vm_interop_handler.dart
2828
typedef enum {
2929
DartDev_Result_Unknown = -1,
30-
DartDev_Result_Run = 1,
31-
DartDev_Result_Exit = 2,
30+
DartDev_Result_RunJIT = 1,
31+
DartDev_Result_RunAOT = 2,
32+
DartDev_Result_Exit = 3,
3233
} DartDev_Result;
3334

3435
// Returns true if there does not exist a file at |script_uri| or the URI is
@@ -58,6 +59,7 @@ class DartDevIsolate {
5859
Dart_IsolateGroupCreateCallback create_isolate,
5960
char** packages_file,
6061
char** script,
62+
CommandLineOptions* vm_options,
6163
CommandLineOptions* dart_options);
6264

6365
protected:
@@ -83,11 +85,11 @@ class DartDevIsolate {
8385
static char** package_config_override_;
8486
static std::unique_ptr<char*[], void (*)(char**)> argv_;
8587
static intptr_t argc_;
88+
static Monitor* monitor_;
8689

8790
Dart_IsolateGroupCreateCallback create_isolate_;
8891
CommandLineOptions* dart_options_;
8992
const char* packages_file_;
90-
static Monitor* monitor_;
9193

9294
DISALLOW_ALLOCATION();
9395
};
@@ -98,6 +100,7 @@ class DartDevIsolate {
98100
static DartDevRunner runner_;
99101
static bool should_run_dart_dev_;
100102
static bool print_usage_error_;
103+
static CommandLineOptions* vm_options_;
101104

102105
DISALLOW_ALLOCATION();
103106
DISALLOW_IMPLICIT_CONSTRUCTORS(DartDevIsolate);

runtime/bin/main_impl.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1417,11 +1417,11 @@ void main(int argc, char** argv) {
14171417
Options::gen_snapshot_kind() == SnapshotKind::kNone) {
14181418
DartDevIsolate::DartDev_Result dartdev_result = DartDevIsolate::RunDartDev(
14191419
CreateIsolateGroupAndSetup, &package_config_override, &script_name,
1420-
&dart_options);
1420+
&vm_options, &dart_options);
14211421
ASSERT(dartdev_result != DartDevIsolate::DartDev_Result_Unknown);
14221422
ran_dart_dev = true;
14231423
should_run_user_program =
1424-
(dartdev_result == DartDevIsolate::DartDev_Result_Run);
1424+
(dartdev_result == DartDevIsolate::DartDev_Result_RunJIT);
14251425
if (should_run_user_program) {
14261426
try_load_snapshots_lambda();
14271427
}

runtime/bin/process.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ void FUNCTION_NAME(Process_Start)(Dart_NativeArguments args) {
114114
const char* path = DartUtils::GetStringValue(path_handle);
115115
Dart_Handle arguments = Dart_GetNativeArgument(args, 3);
116116
intptr_t args_length = 0;
117-
char** string_args =
117+
const char** string_args = const_cast<const char**>(
118118
ExtractCStringList(arguments, status_handle,
119-
"Arguments must be builtin strings", &args_length);
119+
"Arguments must be builtin strings", &args_length));
120120
if (string_args == nullptr) {
121121
Dart_SetBooleanReturnValue(args, false);
122122
return;

runtime/bin/process.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class Process {
9494
// process exit streams.
9595
static int Start(Namespace* namespc,
9696
const char* path,
97-
char* arguments[],
97+
const char* arguments[],
9898
intptr_t arguments_length,
9999
const char* working_directory,
100100
char* environment[],
@@ -114,6 +114,23 @@ class Process {
114114
intptr_t exit_handler,
115115
ProcessResult* result);
116116

117+
// Exec process.
118+
// On systems that support 'exec' it will use it to replace
119+
// the current process image with the image corresponding to 'path'
120+
// On systems that do not support it (Windows) it will start in a
121+
// child process in the same group as the parent so that when the parent
122+
// is killed the child also dies.
123+
// Returns 0 if the process could be execed successfully
124+
// Returns -1 if the exec could not be done successfully and 'errmsg'
125+
// points to the error message
126+
static int Exec(Namespace* namespc,
127+
const char* path,
128+
const char* arguments[],
129+
intptr_t arguments_length,
130+
const char* working_directory,
131+
char* errmsg,
132+
intptr_t errmsg_len);
133+
117134
// Kill a process with a given pid.
118135
static bool Kill(intptr_t id, int signal);
119136

runtime/bin/process_fuchsia.cc

+13
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,19 @@ int Process::Start(Namespace* namespc,
838838
return starter.Start();
839839
}
840840

841+
// The command line dart utility does not run on Fuchsia, this functionality
842+
// is not supported on that platform.
843+
int Process::Exec(Namespace* namespc,
844+
const char* path,
845+
const char** arguments,
846+
const char* working_directory,
847+
char* errmsg,
848+
intptr_t errmsg_len) {
849+
snprintf(errmsg, errmsg_len,
850+
"Process::Exec is not supported on this platform");
851+
return -1;
852+
}
853+
841854
intptr_t Process::SetSignalHandler(intptr_t signal) {
842855
errno = ENOSYS;
843856
return -1;

0 commit comments

Comments
 (0)