[profiling] auto-settings for v8_interpreted_frames Make sure we can set js=False without having to set v8_interpreted_frames as well. This makes it easier to quickly try out a C++-only profile. Drive-by-fix: - Convert empty string "" to None in ObjectParser.optional_bool Change-Id: I0715f11c03085b937b1d5e205c320be5fe6873c0 Reviewed-on: https://chromium-review.googlesource.com/c/crossbench/+/7801017 Commit-Queue: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Victor Vianna <victorvianna@google.com>
diff --git a/crossbench/parse.py b/crossbench/parse.py index f41f870..a77d426 100644 --- a/crossbench/parse.py +++ b/crossbench/parse.py
@@ -550,7 +550,7 @@ value: Any, name: str = "value", strict: bool = False) -> Optional[bool]: - if value is None: + if value is None or value == "": return None return cls.bool(value, name, strict)
diff --git a/crossbench/probes/profiling/system_profiling.py b/crossbench/probes/profiling/system_profiling.py index 4d6cf37..879102e 100644 --- a/crossbench/probes/profiling/system_profiling.py +++ b/crossbench/probes/profiling/system_profiling.py
@@ -87,8 +87,8 @@ "for fewer uninteresting processes.")) parser.add_argument( "v8_interpreted_frames", - type=bool, - default=True, + type=ObjectParser.optional_bool, + default=None, help=( f"Chrome-only: Sets the {V8_INTERPRETED_FRAMES_FLAG} flag for " "V8, which exposes interpreted frames as native frames. " @@ -198,7 +198,7 @@ def __init__( self, js: bool = True, - v8_interpreted_frames: bool = True, + v8_interpreted_frames: Optional[bool] = None, pprof: bool = True, cleanup: CleanupMode = CleanupMode.AUTO, browser_process: bool = False, @@ -220,6 +220,8 @@ self._spare_renderer_process: bool = spare_renderer_process self._run_pprof: bool = pprof self._cleanup_mode = cleanup + if v8_interpreted_frames is None: + v8_interpreted_frames = js self._expose_v8_interpreted_frames: bool = v8_interpreted_frames if v8_interpreted_frames: assert js, "Cannot expose V8 interpreted frames without js profiling." @@ -261,6 +263,10 @@ return self._sample_js @property + def expose_v8_interpreted_frames(self) -> bool: + return self._expose_v8_interpreted_frames + + @property def sample_browser_process(self) -> bool: return self._sample_browser_process
diff --git a/tests/crossbench/probes/profiling/test_system_profiling.py b/tests/crossbench/probes/profiling/test_system_profiling.py index 2880bb5..009b91f 100644 --- a/tests/crossbench/probes/profiling/test_system_profiling.py +++ b/tests/crossbench/probes/profiling/test_system_profiling.py
@@ -313,6 +313,26 @@ self.assertEqual(probe.grouped_events, ("cache-references", "cache-misses")) self.assertEqual(probe.add_counters, ("aa", "bb")) + def test_v8_interpreted_frames_default(self): + probe = ProfilingProbe() + self.assertTrue(probe.expose_v8_interpreted_frames) + + probe = ProfilingProbe(js=False) + self.assertFalse(probe.expose_v8_interpreted_frames) + + probe = ProfilingProbe(js=True, v8_interpreted_frames=False) + self.assertFalse(probe.expose_v8_interpreted_frames) + + with self.assertRaisesRegex(AssertionError, + "Cannot expose V8 interpreted frames"): + ProfilingProbe(js=False, v8_interpreted_frames=True) + + probe = ProfilingProbe.parse_dict({"js": False}) + self.assertFalse(probe.expose_v8_interpreted_frames) + + probe = ProfilingProbe.parse_dict({"js": True}) + self.assertTrue(probe.expose_v8_interpreted_frames) + def test_create_custom_frequency(self): probe = ProfilingProbe.parse_dict({"freq": "max"}) self.assertEqual(probe.frequency, "max")
diff --git a/tests/crossbench/test_parse.py b/tests/crossbench/test_parse.py index 267e0fb..ca77219 100644 --- a/tests/crossbench/test_parse.py +++ b/tests/crossbench/test_parse.py
@@ -634,12 +634,13 @@ def test_parse_optional_bool(self): self.assertIsNone(ObjectParser.optional_bool(None)) + self.assertIsNone(ObjectParser.optional_bool("")) self.assertIs(ObjectParser.optional_bool("true"), True) self.assertIs(ObjectParser.optional_bool("false"), False) def test_parse_optional_bool_invalid(self): invalid: Any - for invalid in (1, 0, "1", "0", "", [], ()): + for invalid in (1, 0, "1", "0", [], ()): with self.assertRaises(argparse.ArgumentTypeError): ObjectParser.optional_bool(invalid) ObjectParser.optional_bool(invalid, strict=True)