1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2008 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.List; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.ArrayList; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.Serializable; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * An operation with a duration. Could represent a class load or initialization. 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass Operation implements Serializable { 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final long serialVersionUID = 0; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Type of operation. 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski enum Type { 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LOAD, INIT 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Process this operation occurred in. */ 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Proc process; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Start time for this operation. */ 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final long startTimeNanos; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Index of this operation relative to its process. */ 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int index; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Type of operation. */ 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Type type; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** End time for this operation. */ 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long endTimeNanos = -1; 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** The class that this operation loaded or initialized. */ 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final LoadedClass loadedClass; 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Other operations that occurred during this one. */ 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final List<Operation> subops = new ArrayList<Operation>(); 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Constructs a new operation. */ 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Operation(Proc process, LoadedClass loadedClass, long startTimeNanos, 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int index, Type type) { 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.process = process; 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.loadedClass = loadedClass; 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.startTimeNanos = startTimeNanos; 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.index = index; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.type = type; 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns how long this class initialization and all the nested class 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * initializations took. 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private long inclusiveTimeNanos() { 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (endTimeNanos == -1) { 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new IllegalStateException("End time hasn't been set yet: " 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + loadedClass.name); 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return endTimeNanos - startTimeNanos; 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns how long this class initialization took. 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int exclusiveTimeMicros() { 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long exclusive = inclusiveTimeNanos(); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Operation child : subops) { 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski exclusive -= child.inclusiveTimeNanos(); 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (exclusive < 0) { 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new AssertionError(loadedClass.name); 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return nanosToMicros(exclusive); 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Gets the median time that this operation took across all processes. */ 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int medianExclusiveTimeMicros() { 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch (type) { 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case LOAD: return loadedClass.medianLoadTimeMicros(); 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case INIT: return loadedClass.medianInitTimeMicros(); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski default: throw new AssertionError(); 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Converts nanoseconds to microseconds. 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @throws RuntimeException if overflow occurs 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static int nanosToMicros(long nanos) { 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long micros = nanos / 1000; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int microsInt = (int) micros; 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (microsInt != micros) { 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new RuntimeException("Integer overflow: " + nanos); 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return microsInt; 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Primarily for debugger support 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public String toString() { 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringBuilder sb = new StringBuilder(); 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sb.append(type.toString()); 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sb.append(' '); 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sb.append(loadedClass.toString()); 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (subops.size() > 0) { 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sb.append(" ("); 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sb.append(subops.size()); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sb.append(" sub ops)"); 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sb.toString(); 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 137