blob: 4f1938e66ebd4da02b5c6a7a53a6c9afb0b5ad54 [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.util.List;
18import java.util.ArrayList;
19import java.io.Serializable;
20
21/**
22 * An operation with a duration. Could represent a class load or initialization.
23 */
24class Operation implements Serializable {
25
26 private static final long serialVersionUID = 0;
27
28 /**
29 * Type of operation.
30 */
31 enum Type {
32 LOAD, INIT
33 }
34
35 /** Process this operation occurred in. */
36 final Proc process;
37
38 /** Start time for this operation. */
39 final long startTimeNanos;
40
41 /** Index of this operation relative to its process. */
42 final int index;
43
44 /** Type of operation. */
45 final Type type;
46
47 /** End time for this operation. */
48 long endTimeNanos = -1;
49
50 /** The class that this operation loaded or initialized. */
51 final LoadedClass loadedClass;
52
53 /** Other operations that occurred during this one. */
54 final List<Operation> subops = new ArrayList<Operation>();
55
56 /** Constructs a new operation. */
57 Operation(Proc process, LoadedClass loadedClass, long startTimeNanos,
58 int index, Type type) {
59 this.process = process;
60 this.loadedClass = loadedClass;
61 this.startTimeNanos = startTimeNanos;
62 this.index = index;
63 this.type = type;
64 }
65
66 /**
67 * Returns how long this class initialization and all the nested class
68 * initializations took.
69 */
70 private long inclusiveTimeNanos() {
71 if (endTimeNanos == -1) {
72 throw new IllegalStateException("End time hasn't been set yet: "
73 + loadedClass.name);
74 }
75
76 return endTimeNanos - startTimeNanos;
77 }
78
79 /**
80 * Returns how long this class initialization took.
81 */
82 int exclusiveTimeMicros() {
83 long exclusive = inclusiveTimeNanos();
84
85 for (Operation child : subops) {
86 exclusive -= child.inclusiveTimeNanos();
87 }
88
89 if (exclusive < 0) {
90 throw new AssertionError(loadedClass.name);
91 }
92
93 return nanosToMicros(exclusive);
94 }
95
96 /** Gets the median time that this operation took across all processes. */
97 int medianExclusiveTimeMicros() {
98 switch (type) {
99 case LOAD: return loadedClass.medianLoadTimeMicros();
100 case INIT: return loadedClass.medianInitTimeMicros();
101 default: throw new AssertionError();
102 }
103 }
104
105 /**
106 * Converts nanoseconds to microseconds.
107 *
108 * @throws RuntimeException if overflow occurs
109 */
110 private static int nanosToMicros(long nanos) {
111 long micros = nanos / 1000;
112 int microsInt = (int) micros;
113 if (microsInt != micros) {
114 throw new RuntimeException("Integer overflow: " + nanos);
115 }
116 return microsInt;
117 }
118
119 /**
120 * Primarily for debugger support
121 */
122 @Override
123 public String toString() {
124 StringBuilder sb = new StringBuilder();
125 sb.append(type.toString());
126 sb.append(' ');
127 sb.append(loadedClass.toString());
128 if (subops.size() > 0) {
129 sb.append(" (");
130 sb.append(subops.size());
131 sb.append(" sub ops)");
132 }
133 return sb.toString();
134 }
135
136}