1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
* Copyright (C) 2008 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.
*/
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
/**
* An operation with a duration. Could represent a class load or initialization.
*/
class Operation implements Serializable {
private static final long serialVersionUID = 0;
/**
* Type of operation.
*/
enum Type {
LOAD, INIT
}
/** Process this operation occurred in. */
final Proc process;
/** Start time for this operation. */
final long startTimeNanos;
/** Index of this operation relative to its process. */
final int index;
/** Type of operation. */
final Type type;
/** End time for this operation. */
long endTimeNanos = -1;
/** The class that this operation loaded or initialized. */
final LoadedClass loadedClass;
/** Other operations that occurred during this one. */
final List<Operation> subops = new ArrayList<Operation>();
/** Constructs a new operation. */
Operation(Proc process, LoadedClass loadedClass, long startTimeNanos,
int index, Type type) {
this.process = process;
this.loadedClass = loadedClass;
this.startTimeNanos = startTimeNanos;
this.index = index;
this.type = type;
}
/**
* Returns how long this class initialization and all the nested class
* initializations took.
*/
private long inclusiveTimeNanos() {
if (endTimeNanos == -1) {
throw new IllegalStateException("End time hasn't been set yet: "
+ loadedClass.name);
}
return endTimeNanos - startTimeNanos;
}
/**
* Returns how long this class initialization took.
*/
int exclusiveTimeMicros() {
long exclusive = inclusiveTimeNanos();
for (Operation child : subops) {
exclusive -= child.inclusiveTimeNanos();
}
if (exclusive < 0) {
throw new AssertionError(loadedClass.name);
}
return nanosToMicros(exclusive);
}
/** Gets the median time that this operation took across all processes. */
int medianExclusiveTimeMicros() {
switch (type) {
case LOAD: return loadedClass.medianLoadTimeMicros();
case INIT: return loadedClass.medianInitTimeMicros();
default: throw new AssertionError();
}
}
/**
* Converts nanoseconds to microseconds.
*
* @throws RuntimeException if overflow occurs
*/
private static int nanosToMicros(long nanos) {
long micros = nanos / 1000;
int microsInt = (int) micros;
if (microsInt != micros) {
throw new RuntimeException("Integer overflow: " + nanos);
}
return microsInt;
}
/**
* Primarily for debugger support
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(type.toString());
sb.append(' ');
sb.append(loadedClass.toString());
if (subops.size() > 0) {
sb.append(" (");
sb.append(subops.size());
sb.append(" sub ops)");
}
return sb.toString();
}
}
|