upload android base code part3
This commit is contained in:
parent
71b83c22f1
commit
b9e30e05b1
15122 changed files with 2089659 additions and 0 deletions
210
android/art/tools/stream-trace-converter.py
Executable file
210
android/art/tools/stream-trace-converter.py
Executable file
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2014 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.
|
||||
|
||||
"""Script that parses a trace filed produced in streaming mode. The file is broken up into
|
||||
a header and body part, which, when concatenated, make up a non-streaming trace file that
|
||||
can be used with traceview."""
|
||||
|
||||
import sys
|
||||
|
||||
class MyException(Exception):
|
||||
pass
|
||||
|
||||
class BufferUnderrun(Exception):
|
||||
pass
|
||||
|
||||
def ReadShortLE(f):
|
||||
byte1 = f.read(1)
|
||||
if not byte1:
|
||||
raise BufferUnderrun()
|
||||
byte2 = f.read(1)
|
||||
if not byte2:
|
||||
raise BufferUnderrun()
|
||||
return ord(byte1) + (ord(byte2) << 8);
|
||||
|
||||
def WriteShortLE(f, val):
|
||||
bytes = [ (val & 0xFF), ((val >> 8) & 0xFF) ]
|
||||
asbytearray = bytearray(bytes)
|
||||
f.write(asbytearray)
|
||||
|
||||
def ReadIntLE(f):
|
||||
byte1 = f.read(1)
|
||||
if not byte1:
|
||||
raise BufferUnderrun()
|
||||
byte2 = f.read(1)
|
||||
if not byte2:
|
||||
raise BufferUnderrun()
|
||||
byte3 = f.read(1)
|
||||
if not byte3:
|
||||
raise BufferUnderrun()
|
||||
byte4 = f.read(1)
|
||||
if not byte4:
|
||||
raise BufferUnderrun()
|
||||
return ord(byte1) + (ord(byte2) << 8) + (ord(byte3) << 16) + (ord(byte4) << 24);
|
||||
|
||||
def WriteIntLE(f, val):
|
||||
bytes = [ (val & 0xFF), ((val >> 8) & 0xFF), ((val >> 16) & 0xFF), ((val >> 24) & 0xFF) ]
|
||||
asbytearray = bytearray(bytes)
|
||||
f.write(asbytearray)
|
||||
|
||||
def Copy(input, output, length):
|
||||
buf = input.read(length)
|
||||
if len(buf) != length:
|
||||
raise BufferUnderrun()
|
||||
output.write(buf)
|
||||
|
||||
class Rewriter:
|
||||
|
||||
def PrintHeader(self, header):
|
||||
header.write('*version\n');
|
||||
header.write('3\n');
|
||||
header.write('data-file-overflow=false\n');
|
||||
header.write('clock=dual\n');
|
||||
header.write('vm=art\n');
|
||||
|
||||
def ProcessDataHeader(self, input, body):
|
||||
magic = ReadIntLE(input)
|
||||
if magic != 0x574f4c53:
|
||||
raise MyException("Magic wrong")
|
||||
|
||||
WriteIntLE(body, magic)
|
||||
|
||||
version = ReadShortLE(input)
|
||||
if (version & 0xf0) != 0xf0:
|
||||
raise MyException("Does not seem to be a streaming trace: %d." % version)
|
||||
version = version ^ 0xf0
|
||||
|
||||
if version != 3:
|
||||
raise MyException("Only support version 3")
|
||||
|
||||
WriteShortLE(body, version)
|
||||
|
||||
# read offset
|
||||
offsetToData = ReadShortLE(input) - 16
|
||||
WriteShortLE(body, offsetToData + 16)
|
||||
|
||||
# copy startWhen
|
||||
Copy(input, body, 8)
|
||||
|
||||
if version == 1:
|
||||
self._mRecordSize = 9;
|
||||
elif version == 2:
|
||||
self._mRecordSize = 10;
|
||||
else:
|
||||
self._mRecordSize = ReadShortLE(input)
|
||||
WriteShortLE(body, self._mRecordSize)
|
||||
offsetToData -= 2;
|
||||
|
||||
# Skip over offsetToData bytes
|
||||
Copy(input, body, offsetToData)
|
||||
|
||||
def ProcessMethod(self, input):
|
||||
stringLength = ReadShortLE(input)
|
||||
str = input.read(stringLength)
|
||||
self._methods.append(str)
|
||||
print 'New method: %s' % str
|
||||
|
||||
def ProcessThread(self, input):
|
||||
tid = ReadShortLE(input)
|
||||
stringLength = ReadShortLE(input)
|
||||
str = input.read(stringLength)
|
||||
self._threads.append('%d\t%s\n' % (tid, str))
|
||||
print 'New thread: %d/%s' % (tid, str)
|
||||
|
||||
def ProcessTraceSummary(self, input):
|
||||
summaryLength = ReadIntLE(input)
|
||||
str = input.read(summaryLength)
|
||||
self._summary = str
|
||||
print 'Summary: \"%s\"' % str
|
||||
|
||||
def ProcessSpecial(self, input):
|
||||
code = ord(input.read(1))
|
||||
if code == 1:
|
||||
self.ProcessMethod(input)
|
||||
elif code == 2:
|
||||
self.ProcessThread(input)
|
||||
elif code == 3:
|
||||
self.ProcessTraceSummary(input)
|
||||
else:
|
||||
raise MyException("Unknown special!")
|
||||
|
||||
def Process(self, input, body):
|
||||
try:
|
||||
while True:
|
||||
threadId = ReadShortLE(input)
|
||||
if threadId == 0:
|
||||
self.ProcessSpecial(input)
|
||||
else:
|
||||
# Regular package, just copy
|
||||
WriteShortLE(body, threadId)
|
||||
Copy(input, body, self._mRecordSize - 2)
|
||||
except BufferUnderrun:
|
||||
print 'Buffer underrun, file was probably truncated. Results should still be usable.'
|
||||
|
||||
def Finalize(self, header):
|
||||
# If the summary is present in the input file, use it as the header except
|
||||
# for the methods section which is emtpy in the input file. If not present,
|
||||
# apppend header with the threads that are recorded in the input stream.
|
||||
if (self._summary):
|
||||
# Erase the contents that's already written earlier by PrintHeader.
|
||||
header.seek(0)
|
||||
header.truncate()
|
||||
# Copy the lines from the input summary to the output header until
|
||||
# the methods section is seen.
|
||||
for line in self._summary.splitlines(True):
|
||||
if line == "*methods\n":
|
||||
break
|
||||
else:
|
||||
header.write(line)
|
||||
else:
|
||||
header.write('*threads\n')
|
||||
for t in self._threads:
|
||||
header.write(t)
|
||||
header.write('*methods\n')
|
||||
for m in self._methods:
|
||||
header.write(m)
|
||||
header.write('*end\n')
|
||||
|
||||
def ProcessFile(self, filename):
|
||||
input = open(filename, 'rb') # Input file
|
||||
header = open(filename + '.header', 'w') # Header part
|
||||
body = open(filename + '.body', 'wb') # Body part
|
||||
|
||||
self.PrintHeader(header)
|
||||
|
||||
self.ProcessDataHeader(input, body)
|
||||
|
||||
self._methods = []
|
||||
self._threads = []
|
||||
self._summary = None
|
||||
self.Process(input, body)
|
||||
|
||||
self.Finalize(header)
|
||||
|
||||
input.close()
|
||||
header.close()
|
||||
body.close()
|
||||
|
||||
def main():
|
||||
Rewriter().ProcessFile(sys.argv[1])
|
||||
header_name = sys.argv[1] + '.header'
|
||||
body_name = sys.argv[1] + '.body'
|
||||
print 'Results have been written to %s and %s.' % (header_name, body_name)
|
||||
print 'Concatenate the files to get a result usable with traceview.'
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue