blob: 53519b72686b9b7eb5fe4840b952b1d74d04c6ea [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tradefed.util;
import com.android.tradefed.log.LogUtil.CLog;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** Helper class to parse info from an Allocation Sites section of hprof reports. */
public class HprofAllocSiteParser {
private static final String ALLOC_SITES_START_PATTERN = "SITES BEGIN";
private static final String ALLOC_SITES_END_PATTERN = "SITES END";
private boolean mHasAllocSiteStarted = false;
// format:
// percent live alloc'ed stack class
// rank self accum bytes objs bytes objs trace name
// 1 12.24% 12.24% 12441616 1 12441616 1 586322 byte[]
private static final Pattern RANK_PATTERN =
Pattern.compile(
"(\\s+)([0-9]*)(\\s+)([0-9]*\\.?[0-9]+%)(\\s+)([0-9]*\\.?[0-9]+%)(\\s+)"
+ "([0-9]+)(\\s+)([0-9]+)(\\s+)([0-9]+)(\\s+)([0-9]+)(\\s+)([0-9]+)"
+ "(\\s+)(.*)");
/**
* Parse a text hprof report.
*
* @param hprofReport file containing the hprof report.
* @return a Map containing the results
*/
public Map<String, String> parse(File hprofReport) throws IOException {
Map<String, String> results = new HashMap<>();
if (hprofReport == null || !hprofReport.exists()) {
return results;
}
internalParse(hprofReport, results);
return results;
}
/**
* Actual parsing line by line of the report to extract information.
*
* @param report the {@link File} containing the hprof report.
* @param currentRes the {@link Map} where the allocation sites will be stored.
*/
private void internalParse(File report, Map<String, String> currentRes) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(report))) {
for (String line; (line = br.readLine()) != null; ) {
handleAllocSites(line, currentRes);
}
}
}
/** Handles the allocation sites in the hprof report. */
private void handleAllocSites(String line, Map<String, String> currentRes) {
if (line.startsWith(ALLOC_SITES_START_PATTERN)) {
mHasAllocSiteStarted = true;
} else if (line.startsWith(ALLOC_SITES_END_PATTERN)) {
mHasAllocSiteStarted = false;
} else if (mHasAllocSiteStarted) {
Matcher m = RANK_PATTERN.matcher(line);
if (m.find()) {
CLog.d(
"Rank %s-%s-%s-%s-%s-%s-%s-%s-%s",
m.group(2),
m.group(4),
m.group(6),
m.group(8),
m.group(10),
m.group(12),
m.group(14),
m.group(16),
m.group(18));
currentRes.put(String.format("Rank%s", m.group(2)), m.group(12));
}
}
}
}