[vm] Make --code-comments a VM global flag.

This way, it is appropriately enabled if possible during snapshot
loading if the snapshot was compiled with --code-comments, instead of
forcing the user to remember to run the snapshot loader with
--code-comments to avoid a runtime failure.

TEST=vm/dart{,_2}/use_code_comments_flag_test

Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try
Change-Id: Ib3de04ecbd95ee4069c3d31ef3e4dc4b2a3ac94c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196668
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
diff --git a/runtime/tests/vm/dart/use_code_comments_flag_test.dart b/runtime/tests/vm/dart/use_code_comments_flag_test.dart
new file mode 100644
index 0000000..cc3968c
--- /dev/null
+++ b/runtime/tests/vm/dart/use_code_comments_flag_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2021, 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.
+
+// This test is ensuring that the flag for --code-comments given at
+// AOT compile-time will be used at runtime (irrespective if other values were
+// passed to the runtime).
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  await withTempDir('code-comments-test', (String tempDir) async {
+    final script = path.join(sdkDir, 'pkg/kernel/bin/dump.dart');
+    final scriptDill = path.join(tempDir, 'kernel_dump.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with/without code comments.
+    final scriptCommentedSnapshot = path.join(tempDir, 'comments.snapshot');
+    final scriptUncommentedSnapshot =
+        path.join(tempDir, 'no_comments.snapshot');
+    await Future.wait(<Future>[
+      run(genSnapshot, <String>[
+        '--code-comments',
+        '--snapshot-kind=app-aot-elf',
+        '--elf=$scriptCommentedSnapshot',
+        scriptDill,
+      ]),
+      run(genSnapshot, <String>[
+        '--no-code-comments',
+        '--snapshot-kind=app-aot-elf',
+        '--elf=$scriptUncommentedSnapshot',
+        scriptDill,
+      ]),
+    ]);
+
+    // Run the AOT compiled script with code comments enabled.
+    final commentsOut1 = path.join(tempDir, 'comments-out1.txt');
+    final commentsOut2 = path.join(tempDir, 'comments-out2.txt');
+    await Future.wait(<Future>[
+      run(aotRuntime, <String>[
+        '--code-comments',
+        scriptCommentedSnapshot,
+        scriptDill,
+        commentsOut1,
+      ]),
+      run(aotRuntime, <String>[
+        '--no-code-comments',
+        scriptCommentedSnapshot,
+        scriptDill,
+        commentsOut2,
+      ]),
+    ]);
+
+    // Run the AOT compiled script with code comments disabled.
+    final uncommentedOut1 = path.join(tempDir, 'uncommented-out1.txt');
+    final uncommentedOut2 = path.join(tempDir, 'uncommented-out2.txt');
+    await Future.wait(<Future>[
+      run(aotRuntime, <String>[
+        '--code-comments',
+        scriptUncommentedSnapshot,
+        scriptDill,
+        uncommentedOut1,
+      ]),
+      run(aotRuntime, <String>[
+        '--no-code-comments',
+        scriptUncommentedSnapshot,
+        scriptDill,
+        uncommentedOut2,
+      ]),
+    ]);
+
+    // Ensure we got the same result each time.
+    final output = await File(commentsOut1).readAsString();
+    Expect.equals(output, await File(commentsOut2).readAsString());
+    Expect.equals(output, await File(uncommentedOut1).readAsString());
+    Expect.equals(output, await File(uncommentedOut2).readAsString());
+  });
+}
diff --git a/runtime/tests/vm/dart_2/use_code_comments_flag_test.dart b/runtime/tests/vm/dart_2/use_code_comments_flag_test.dart
new file mode 100644
index 0000000..cc3968c
--- /dev/null
+++ b/runtime/tests/vm/dart_2/use_code_comments_flag_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2021, 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.
+
+// This test is ensuring that the flag for --code-comments given at
+// AOT compile-time will be used at runtime (irrespective if other values were
+// passed to the runtime).
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  await withTempDir('code-comments-test', (String tempDir) async {
+    final script = path.join(sdkDir, 'pkg/kernel/bin/dump.dart');
+    final scriptDill = path.join(tempDir, 'kernel_dump.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with/without code comments.
+    final scriptCommentedSnapshot = path.join(tempDir, 'comments.snapshot');
+    final scriptUncommentedSnapshot =
+        path.join(tempDir, 'no_comments.snapshot');
+    await Future.wait(<Future>[
+      run(genSnapshot, <String>[
+        '--code-comments',
+        '--snapshot-kind=app-aot-elf',
+        '--elf=$scriptCommentedSnapshot',
+        scriptDill,
+      ]),
+      run(genSnapshot, <String>[
+        '--no-code-comments',
+        '--snapshot-kind=app-aot-elf',
+        '--elf=$scriptUncommentedSnapshot',
+        scriptDill,
+      ]),
+    ]);
+
+    // Run the AOT compiled script with code comments enabled.
+    final commentsOut1 = path.join(tempDir, 'comments-out1.txt');
+    final commentsOut2 = path.join(tempDir, 'comments-out2.txt');
+    await Future.wait(<Future>[
+      run(aotRuntime, <String>[
+        '--code-comments',
+        scriptCommentedSnapshot,
+        scriptDill,
+        commentsOut1,
+      ]),
+      run(aotRuntime, <String>[
+        '--no-code-comments',
+        scriptCommentedSnapshot,
+        scriptDill,
+        commentsOut2,
+      ]),
+    ]);
+
+    // Run the AOT compiled script with code comments disabled.
+    final uncommentedOut1 = path.join(tempDir, 'uncommented-out1.txt');
+    final uncommentedOut2 = path.join(tempDir, 'uncommented-out2.txt');
+    await Future.wait(<Future>[
+      run(aotRuntime, <String>[
+        '--code-comments',
+        scriptUncommentedSnapshot,
+        scriptDill,
+        uncommentedOut1,
+      ]),
+      run(aotRuntime, <String>[
+        '--no-code-comments',
+        scriptUncommentedSnapshot,
+        scriptDill,
+        uncommentedOut2,
+      ]),
+    ]);
+
+    // Ensure we got the same result each time.
+    final output = await File(commentsOut1).readAsString();
+    Expect.equals(output, await File(commentsOut2).readAsString());
+    Expect.equals(output, await File(uncommentedOut1).readAsString());
+    Expect.equals(output, await File(uncommentedOut2).readAsString());
+  });
+}
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d389089..53250c5 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -976,10 +976,6 @@
                              FLAG_use_field_guards);
       ADD_ISOLATE_GROUP_FLAG(use_osr, use_osr, FLAG_use_osr);
     }
-#if !defined(PRODUCT)
-    buffer.AddString(FLAG_code_comments ? " code-comments"
-                                        : " no-code-comments");
-#endif
 
 // Generated code must match the host architecture and ABI.
 #if defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 59226e1..1aa3e56 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -60,6 +60,7 @@
 // automatically included in FLAG_LIST.
 // TODO(cskau): Remove causal_async_stacks when deprecated.
 #define VM_GLOBAL_FLAG_LIST(P, R, C, D)                                        \
+  P(code_comments, bool, false, "Include comments into code and disassembly.") \
   P(dwarf_stack_traces_mode, bool, false,                                      \
     "Use --[no-]dwarf-stack-traces instead.")                                  \
   P(causal_async_stacks, bool, false, "DEPRECATED: Improved async stacks")     \
@@ -98,7 +99,6 @@
     "Run optimizing compilation in background")                                \
   P(check_token_positions, bool, false,                                        \
     "Check validity of token positions while compiling flow graphs")           \
-  P(code_comments, bool, false, "Include comments into code and disassembly.") \
   P(collect_code, bool, false, "Attempt to GC infrequently used code.")        \
   P(collect_dynamic_function_names, bool, true,                                \
     "Collects all dynamic function names to identify unique targets")          \