diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index d5c64a8e83c0e6..bfc93c7d444980 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -86,6 +86,7 @@ !/third_party/v8 !/third_party/wasm-api /tools/builtins-pgo/profiles/*.profile +/tools/builtins-pgo/profiles/profiles_version /tools/clang /tools/gcmole/bootstrap /tools/gcmole/gcmole-tools diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index a3c31c5b29cc3c..e665e9b67dfc98 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 12 #define V8_MINOR_VERSION 4 #define V8_BUILD_NUMBER 254 -#define V8_PATCH_LEVEL 20 +#define V8_PATCH_LEVEL 21 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/tools/builtins-pgo/download_profiles.py b/deps/v8/tools/builtins-pgo/download_profiles.py index 23eb871e8371b3..e5adb339c29254 100755 --- a/deps/v8/tools/builtins-pgo/download_profiles.py +++ b/deps/v8/tools/builtins-pgo/download_profiles.py @@ -11,6 +11,7 @@ """ import argparse +import contextlib import os import pathlib import re @@ -79,6 +80,12 @@ def parse_args(cmd_args): default=DEPOT_TOOLS_DEFAULT_PATH, ) + parser.add_argument( + '--force', + help=('force download, overwriting existing profiles'), + action='store_true', + ) + return parser.parse_args(cmd_args) @@ -109,14 +116,45 @@ def retrieve_version(args): return version +def download_profiles(version_path, requested_version, args): + if args.force: + return True + + if not version_path.is_file(): + return True + + with open(version_path) as version_file: + profiles_version = version_file.read() + + if profiles_version != requested_version: + return True + + print('Profiles already downloaded, use --force to overwrite.') + return False + + +@contextlib.contextmanager +def ensure_profiles(version, args): + version_path = PGO_PROFILE_DIR / 'profiles_version' + require_profiles = download_profiles(version_path, version, args) + yield require_profiles + if require_profiles: + with open(version_path, 'w') as version_file: + version_file.write(version) + + def perform_action(version, args): path = f'{PGO_PROFILE_BUCKET}/by-version/{version}' if args.action == 'download': - cmd = ['cp', '-R', f'gs://{path}/*.profile', str(PGO_PROFILE_DIR)] - failure_hint = f'https://storage.googleapis.com/{path} does not exist.' - call_gsutil(cmd, failure_hint) - return + with ensure_profiles(version, args) as require_profiles: + if not require_profiles: + return + + cmd = ['cp', '-R', f'gs://{path}/*.profile', str(PGO_PROFILE_DIR)] + failure_hint = f'https://storage.googleapis.com/{path} does not exist.' + call_gsutil(cmd, failure_hint) + return if args.action == 'validate': meta_json = f'{path}/meta.json' diff --git a/deps/v8/tools/builtins-pgo/download_profiles_test.py b/deps/v8/tools/builtins-pgo/download_profiles_test.py index a326f5e17f463e..5e0e03fffa3927 100644 --- a/deps/v8/tools/builtins-pgo/download_profiles_test.py +++ b/deps/v8/tools/builtins-pgo/download_profiles_test.py @@ -7,6 +7,7 @@ import contextlib import io import os +import pathlib import unittest from tempfile import TemporaryDirectory @@ -34,12 +35,31 @@ def test_validate_profiles(self): def test_download_profiles(self): with TemporaryDirectory() as td, \ - patch('download_profiles.PGO_PROFILE_DIR', td): + patch('download_profiles.PGO_PROFILE_DIR', pathlib.Path(td)): out, err = self._test_cmd(['download', '--version', '11.1.0.0'], 0) self.assertEqual(len(out), 0) self.assertEqual(len(err), 0) self.assertGreater( len([f for f in os.listdir(td) if f.endswith('.profile')]), 0) + with open(pathlib.Path(td) / 'profiles_version') as f: + self.assertEqual(f.read(), '11.1.0.0') + + # A second download should not be started as profiles exist already + with patch('download_profiles.call_gsutil') as gsutil: + out, err = self._test_cmd(['download', '--version', '11.1.0.0'], 0) + self.assertEqual( + out, + 'Profiles already downloaded, use --force to overwrite.\n', + ) + gsutil.assert_not_called() + + # A forced download should always trigger + with patch('download_profiles.call_gsutil') as gsutil: + cmd = ['download', '--version', '11.1.0.0', '--force'] + out, err = self._test_cmd(cmd, 0) + self.assertEqual(len(out), 0) + self.assertEqual(len(err), 0) + gsutil.assert_called_once() def test_invalid_args(self): out, err = self._test_cmd(['invalid-action'], 2) @@ -83,14 +103,18 @@ def test_retrieve_parameter_version(self): self.assertEqual(version, '11.1.1.42') def test_retrieve_untagged_version(self): + out = io.StringIO() with patch( 'builtins.open', new=mock_open(read_data=self.mock_version_file(11, 4, 0, 0))), \ + contextlib.redirect_stdout(out), \ self.assertRaises(SystemExit) as se: args = parse_args(['download']) version = retrieve_version(args) self.assertEqual(se.exception.code, 0) + self.assertEqual(out.getvalue(), + 'The version file specifies 11.4.0.0, which has no profiles.\n') if __name__ == '__main__': unittest.main()