diff options
author | Tamas Kenez <tamaskenez@google.com> | 2017-07-13 12:43:57 +0200 |
---|---|---|
committer | Tamas Kenez <tamaskenez@google.com> | 2017-07-13 12:43:57 +0200 |
commit | fc34cd80f0abbae2372f5d8203363ecc2cd58f08 (patch) | |
tree | 9b2fd72ae1b624f456b646ec8bcd927bb2032718 | |
parent | b2a918cdeabe753e599d63149afdd61f0a9d0547 (diff) | |
download | r8-fc34cd80f0abbae2372f5d8203363ecc2cd58f08.tar.gz |
Add memory usage tracking to test scripts.
Bug:
Change-Id: Ifb0742fb47f4031c973ad39ec09627270bc357ea
-rwxr-xr-x | tools/proguard.py | 9 | ||||
-rwxr-xr-x | tools/run_on_app.py | 59 | ||||
-rwxr-xr-x | tools/run_proguard_dx_on_gmscore.py | 34 | ||||
-rwxr-xr-x | tools/test_framework.py | 22 | ||||
-rw-r--r-- | tools/utils.py | 23 |
5 files changed, 116 insertions, 31 deletions
diff --git a/tools/proguard.py b/tools/proguard.py index 58c049f9e..efcf560d2 100755 --- a/tools/proguard.py +++ b/tools/proguard.py @@ -15,10 +15,13 @@ import utils PROGUARD_JAR = os.path.join(utils.REPO_ROOT, 'third_party', 'proguard', 'proguard_internal_159423826', 'ProGuard_deploy.jar') -def run(args): - cmd = ['java', '-jar', PROGUARD_JAR] +def run(args, track_memory_file = None): + cmd = [] + if track_memory_file: + cmd.extend(['tools/track_memory.sh', track_memory_file]) + cmd.extend(['java', '-jar', PROGUARD_JAR]) cmd.extend(args) - print('-- ' + ' '.join(cmd)) + utils.PrintCmd(cmd) subprocess.check_call(cmd) def Main(): diff --git a/tools/run_on_app.py b/tools/run_on_app.py index f3cc9b5ca..d7db7fb16 100755 --- a/tools/run_on_app.py +++ b/tools/run_on_app.py @@ -3,6 +3,7 @@ # 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. +from __future__ import print_function import optparse import os import sys @@ -55,8 +56,11 @@ def ParseOptions(): 'If passing several options use a quoted string.') result.add_option('--r8-flags', help='Additional option(s) for the compiler. ' + - 'Same as --compiler-flags, keeping it for backward compatibility. ' + + 'Same as --compiler-flags, keeping it for backward' + ' compatibility. ' + 'If passing several options use a quoted string.') + # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem + # to use --print-memoryuse instead result.add_option('--track-memory-to-file', help='Track how much memory the jvm is using while ' + ' compiling. Output to the specified file.') @@ -73,6 +77,11 @@ def ParseOptions(): help='Prints the line \'<BENCHMARKNAME>(RunTimeRaw):' + ' <elapsed> ms\' at the end where <elapsed> is' + ' the elapsed time in milliseconds.') + result.add_option('--print-memoryuse', + metavar='BENCHMARKNAME', + help='Prints the line \'<BENCHMARKNAME>(MemoryUse):' + + ' <mem>\' at the end where <mem> is the peak' + + ' peak resident set size (VmHWM) in bytes.') return result.parse_args() # Most apps have the -printmapping and -printseeds in the Proguard @@ -81,10 +90,10 @@ def ParseOptions(): # placing these two output files together with the dex output. def GenerateAdditionalProguardConfiguration(temp, outdir): name = "output.config" - with open(os.path.join(temp, name), 'w') as file: - file.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n") - file.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n") - return os.path.abspath(file.name) + with open(os.path.join(temp, name), 'w') as f: + f.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n") + f.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n") + return os.path.abspath(f.name) def main(): app_provided_pg_conf = False; @@ -104,8 +113,9 @@ def main(): raise 'Unexpected' if not options.version in data.VERSIONS.keys(): - print 'No version %s for application %s' % (options.version, options.app) - print 'Valid versions are %s' % data.VERSIONS.keys() + print('No version {} for application {}' + .format(options.version, options.app)) + print('Valid versions are {}'.format(data.VERSIONS.keys())) return 1 version = data.VERSIONS[options.version] @@ -115,13 +125,15 @@ def main(): else 'proguarded' if options.type not in version: - print 'No type %s for version %s' % (options.type, options.version) - print 'Valid types are %s' % version.keys() + print('No type {} for version {}'.format(options.type, options.version)) + print('Valid types are {}'.format(version.keys())) return 1 values = version[options.type] inputs = None - # For R8 'deploy' the JAR is located using the Proguard configuration -injars option. - if 'inputs' in values and (options.compiler != 'r8' or options.type != 'deploy'): + # For R8 'deploy' the JAR is located using the Proguard configuration + # -injars option. + if 'inputs' in values and (options.compiler != 'r8' + or options.type != 'deploy'): inputs = values['inputs'] args.extend(['--output', outdir]) @@ -145,7 +157,8 @@ def main(): for lib in values['libraries']: args.extend(['--lib', lib]) - if not outdir.endswith('.zip') and not outdir.endswith('.jar') and not os.path.exists(outdir): + if not outdir.endswith('.zip') and not outdir.endswith('.jar') \ + and not os.path.exists(outdir): os.makedirs(outdir) if options.compiler == 'r8': @@ -161,16 +174,18 @@ def main(): args.extend(inputs) t0 = time.time() - if options.dump_args_file: with open(options.dump_args_file, 'w') as args_file: args_file.writelines([arg + os.linesep for arg in args]) else: - if options.compiler == 'd8': - d8.run(args, not options.no_build, not options.no_debug, options.profile, - options.track_memory_to_file) - else: - with utils.TempDir() as temp: + with utils.TempDir() as temp: + if options.print_memoryuse and not options.track_memory_to_file: + options.track_memory_to_file = os.path.join(temp, + utils.MEMORY_USE_TMP_FILE) + if options.compiler == 'd8': + d8.run(args, not options.no_build, not options.no_debug, + options.profile, options.track_memory_to_file) + else: if app_provided_pg_conf: # Ensure that output of -printmapping and -printseeds go to the output # location and not where the app Proguard configuration places them. @@ -181,8 +196,12 @@ def main(): additional_pg_conf = GenerateAdditionalProguardConfiguration( temp, os.path.abspath(pg_outdir)) args.extend(['--pg-conf', additional_pg_conf]) - r8.run(args, not options.no_build, not options.no_debug, options.profile, - options.track_memory_to_file) + r8.run(args, not options.no_build, not options.no_debug, + options.profile, options.track_memory_to_file) + if options.print_memoryuse: + print('{}(MemoryUse): {}' + .format(options.print_memoryuse, + utils.grep_memoryuse(options.track_memory_to_file))) if options.print_runtimeraw: print('{}(RunTimeRaw): {} ms' diff --git a/tools/run_proguard_dx_on_gmscore.py b/tools/run_proguard_dx_on_gmscore.py index ca0b5e9e9..de716b082 100755 --- a/tools/run_proguard_dx_on_gmscore.py +++ b/tools/run_proguard_dx_on_gmscore.py @@ -40,6 +40,11 @@ def parse_arguments(): help = 'Prints the line \'<BENCHMARKNAME>(RunTimeRaw): <elapsed>' + ' ms\' at the end where <elapsed> is the elapsed time in' + ' milliseconds.') + parser.add_argument('--print-memoryuse', + metavar='BENCHMARKNAME', + help='Prints the line \'<BENCHMARKNAME>(MemoryUse):' + + ' <mem>\' at the end where <mem> is the peak' + + ' peak resident set size (VmHWM) in bytes.') parser.add_argument('--compatdx', help = 'Use CompatDx (D8) instead of DX.', default = False, @@ -72,7 +77,15 @@ def Main(): t0 = time.time() - proguard.run(args) + proguard_memoryuse = None + + with utils.TempDir() as temp: + track_memory_file = None + if options.print_memoryuse: + track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE) + proguard.run(args, track_memory_file = track_memory_file) + if options.print_memoryuse: + proguard_memoryuse = utils.grep_memoryuse(track_memory_file) # run dex on the result if options.compatdx: @@ -80,10 +93,21 @@ def Main(): else: jar = DX_JAR - cmd = ['java', '-jar', jar, '--min-sdk-version=26', '--multi-dex', - '--output=' + outdir, '--dex', PROGUARDED_OUTPUT]; - utils.PrintCmd(cmd); - check_call(cmd) + with utils.TempDir() as temp: + track_memory_file = None + cmd = [] + if options.print_memoryuse: + track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE) + cmd.extend(['tools/track_memory.sh', track_memory_file]) + cmd.extend(['java', '-jar', jar, '--min-sdk-version=26', '--multi-dex', + '--output=' + outdir, '--dex', PROGUARDED_OUTPUT]); + utils.PrintCmd(cmd); + check_call(cmd) + if options.print_memoryuse: + dx_memoryuse = utils.grep_memoryuse(track_memory_file) + print('{}(MemoryUse): {}' + .format(options.print_memoryuse, + max(proguard_memoryuse, dx_memoryuse))) if options.print_runtimeraw: print('{}(RunTimeRaw): {} ms' diff --git a/tools/test_framework.py b/tools/test_framework.py index 810935d18..57279bfb4 100755 --- a/tools/test_framework.py +++ b/tools/test_framework.py @@ -53,6 +53,12 @@ def parse_arguments(): required = True, help = 'Results will be printed using the specified benchmark name (e.g.' ' <NAME>-<segment>(CodeSize): <bytes>)') + parser.add_argument('--print-memoryuse', + help = 'Prints the line \'<NAME>(MemoryUse):' + + ' <mem>\' at the end where <mem> is the peak' + + ' peak resident set size (VmHWM) in bytes.', + default = False, + action = 'store_true') return parser.parse_args() # Return a dictionary: {segment_name -> segments_size} @@ -96,10 +102,16 @@ def Main(): if args.tool == 'd8-release': tool_args.append('--release') + + cmd = [] + + track_memory_file = None + if args.print_memoryuse: + track_memory_file = os.path.join(temp_dir, utils.MEMORY_USE_TMP_FILE) + cmd.extend(['tools/track_memory.sh', track_memory_file]) + if tool_file.endswith('.jar'): - cmd = ['java', '-jar'] - else: - cmd = [] + cmd.extend(['java', '-jar']) cmd.extend([tool_file] + tool_args + [FRAMEWORK_JAR]) @@ -109,6 +121,10 @@ def Main(): subprocess.check_call(cmd) dt = time.time() - t0 + if args.print_memoryuse: + print('{}(MemoryUse): {}' + .format(args.name, utils.grep_memoryuse(track_memory_file))) + dex_files = [f for f in glob(os.path.join(temp_dir, '*.dex'))] code_size = 0 for dex_file in dex_files: diff --git a/tools/utils.py b/tools/utils.py index fd7212bd7..2564adc2e 100644 --- a/tools/utils.py +++ b/tools/utils.py @@ -14,6 +14,7 @@ import tempfile TOOLS_DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..'))) REPO_ROOT = os.path.realpath(os.path.join(TOOLS_DIR, '..')) +MEMORY_USE_TMP_FILE = 'memory_use.tmp' def PrintCmd(s): if type(s) is list: @@ -118,3 +119,25 @@ def read_cts_test_result(file_xml): outcome = m.groups()[0] assert outcome in ['fail', 'pass'] yield CtsTest(m.groups()[1], outcome == 'pass') + +def grep_memoryuse(logfile): + re_vmhwm = re.compile('^VmHWM:[ \t]*([0-9]+)[ \t]*([a-zA-Z]*)') + result = None + with open(logfile) as f: + for line in f: + m = re_vmhwm.search(line) + if m: + groups = m.groups() + s = len(groups) + if s >= 1: + result = int(groups[0]) + if s >= 2: + unit = groups[1] + if unit == 'kB': + result *= 1024 + elif unit != '': + raise Exception('Unrecognized unit in memory usage log: {}' + .format(unit)) + if result is None: + raise Exception('No memory usage found in log: {}'.format(logfile)) + return result
\ No newline at end of file |