aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Kotsiuba <artem.kotsiuba@linaro.org>2021-10-06 16:36:53 +0100
committerArtem Kotsiuba <artem.kotsiuba@linaro.org>2021-10-26 12:37:10 +0100
commitb4dc5f35ea66849ac66cd9e22b4ec1ef5d7a098d (patch)
treebf0cb228d21d49629ce277fa3405605d47fe2d12
parent6c10ff22fc1a2461a5c8554780a64d108defa455 (diff)
downloadart-testing-b4dc5f35ea66849ac66cd9e22b4ec1ef5d7a098d.tar.gz
ART: Add boot.oat support to compile statistics scripts
This change adds functionality to collect compilation statistics when compiling boot.oat. Compilation of boot.oat produces multiple files (.oat, .vdex and .art). The tool collects statistics only for .oat files (boot.oat, boot-core-libart.oat, boot-okhttp.oat, boot-apache-xml.oat and boot-bouncycastle.oat) and outputs it to .json file using name of the output file as a key. Test: ./scripts/benchmarks/compilation_stats_target.sh boot.oat --iterations 2 --skip-build python3 ./benchmarks/test/test.py Change-Id: I05a0a7f8e30329e23c9d76bf617088489f8fcd8e
-rwxr-xr-xcompilation_stats.py35
-rwxr-xr-xtools/benchmarks/run.py8
-rw-r--r--tools/utils.py17
3 files changed, 36 insertions, 24 deletions
diff --git a/compilation_stats.py b/compilation_stats.py
index 78dea5f..34fa3d7 100755
--- a/compilation_stats.py
+++ b/compilation_stats.py
@@ -39,20 +39,18 @@ def BuildOptions():
args = parser.parse_args()
return args
-def SaveAndPrintResults(apk,
+def SaveAndPrintResults(target_file_key,
compilation_times,
section_sizes,
output_json_filename):
output_obj = utils.ReadJSON(output_json_filename)
+ output_obj[target_file_key] = dict()
- apk_basename = os.path.basename(apk)
- output_obj[apk_basename] = dict()
-
- output_obj[apk_basename].update(compilation_times)
+ output_obj[target_file_key].update(compilation_times)
print("Compilation times (seconds):")
utils.PrintData(compilation_times)
- output_obj[apk_basename]["Executable size"] = section_sizes
+ output_obj[target_file_key]["Executable size"] = section_sizes
print("Executable sizes (bytes):")
utils.PrintData(section_sizes)
@@ -65,8 +63,7 @@ if __name__ == "__main__":
work_dir = tempfile.mkdtemp()
try:
args = BuildOptions()
- apk = args.add_pathname[0]
- apk_name = utils.TargetPathJoin(args.target_copy_path, apk)
+ input_filename = args.add_pathname[0]
# command is used to call a shell script using chroot
# this script calls dex2oat on a given APK and prints
# before/after timestamps
@@ -76,8 +73,11 @@ if __name__ == "__main__":
command = os.getenv('ART_COMMAND')
else:
utils.Error("ART_COMMAND is not set.")
- format_data = {'workdir': os.path.dirname(apk_name)}
- command = command.format(**format_data)
+
+ if input_filename != "boot.oat":
+ apk_name = utils.TargetPathJoin(args.target_copy_path, input_filename)
+ format_data = {'workdir': os.path.dirname(apk_name)}
+ command = command.format(**format_data)
compilation_times = []
for i in range(args.iterations):
@@ -88,14 +88,17 @@ if __name__ == "__main__":
compilation_times += [compilation_time]
print("Compilation took {:.2f}s\n".format(compilation_time))
- # Pull the executable and get its size
- local_oat = os.path.join(work_dir, apk + '.oat')
- utils_adb.pull(args.output_oat, local_oat, args.target)
- section_sizes = utils.GetSectionSizes(local_oat)
-
compile_time_dict = OrderedDict([("Time", compilation_times)])
- SaveAndPrintResults(apk, compile_time_dict, section_sizes, args.output_json)
+ # Pull the executable and get its size
+ for output_oat in args.output_oat:
+ print("Getting size for {}".format(output_oat))
+ output_filename = os.path.basename(output_oat)
+ local_oat = os.path.join(work_dir, output_filename)
+ utils_adb.pull(output_oat, local_oat, args.target)
+ section_sizes = utils.GetSectionSizes(local_oat)
+
+ SaveAndPrintResults(output_filename, compile_time_dict, section_sizes, args.output_json)
finally:
shutil.rmtree(work_dir)
diff --git a/tools/benchmarks/run.py b/tools/benchmarks/run.py
index 844d484..fb48eec 100755
--- a/tools/benchmarks/run.py
+++ b/tools/benchmarks/run.py
@@ -183,7 +183,7 @@ def RunBench(apk, classname,
def RunBenchs(apk, bench_names,
target,
- output_oat,
+ output_oats,
auto_calibrate,
iterations=utils.default_n_iterations,
mode=utils.default_mode,
@@ -204,11 +204,13 @@ def RunBenchs(apk, bench_names,
android_root = android_root,
target = target,
cpuset = cpuset)
- if output_oat is not None:
+ if output_oats is not None:
try:
+ assert len(output_oats) == 1, \
+ "When setting up microbenchmarks, only one .oat file is expected"
work_dir = tempfile.mkdtemp()
local_oat = os.path.join(work_dir, 'bench.oat')
- utils_adb.pull(output_oat, local_oat, target)
+ utils_adb.pull(output_oats[0], local_oat, target)
section_sizes = utils.GetSectionSizes(local_oat)
result[utils.compilation_statistics_label] = section_sizes
finally:
diff --git a/tools/utils.py b/tools/utils.py
index b2e5e3d..8ac1a20 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -190,6 +190,7 @@ def AddCommonRunOptions(parser):
default = None,
help = 'Add pathnames to be considered for compilation statistics.')
opts.add_argument('--output-oat',
+ nargs='+',
default=None,
help = 'Full name of the compiled executable file')
@@ -505,10 +506,16 @@ def ExtractCompilationTimeFromOutput(lines):
return timestamp_after - timestamp_before
def GetSectionSizes(path_to_executable):
+ section_sizes = OrderedDict()
+
command = ['size', '-A', '-d', path_to_executable]
- rc, outerr = Command(command)
- section_sizes = OrderedDict(
- (section_line[0], [int(section_line[1])]) for section_line
- in re.findall('(\S+)\s+([0-9]+).*', outerr)
- if section_line[0] in sections)
+ rc, outerr = Command(command, exit_on_error=False)
+ if rc == 0:
+ section_sizes = OrderedDict(
+ (section_line[0], [int(section_line[1])]) for section_line
+ in re.findall('(\S+)\s+([0-9]+).*', outerr)
+ if section_line[0] in sections)
+ else:
+ Error("Using size failed. Please check that target file exists and "
+ "that it is a valid ELF file")
return section_sizes