diff options
Diffstat (limited to 'tools/preload/Proc.java')
-rw-r--r-- | tools/preload/Proc.java | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/tools/preload/Proc.java b/tools/preload/Proc.java new file mode 100644 index 0000000..2105021 --- /dev/null +++ b/tools/preload/Proc.java @@ -0,0 +1,168 @@ +/* + * 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.util.LinkedList; +import java.util.Map; +import java.util.HashMap; +import java.io.Serializable; + +/** + * A Dalvik process. + */ +class Proc implements Serializable { + + private static final long serialVersionUID = 0; + + /** Parent process. */ + final Proc parent; + + /** Process ID. */ + final int id; + + /** + * Name of this process. We may not have the correct name at first, i.e. + * some classes could have been loaded before the process name was set. + */ + String name; + + /** Child processes. */ + final List<Proc> children = new ArrayList<Proc>(); + + /** Maps thread ID to operation stack. */ + transient final Map<Integer, LinkedList<Operation>> stacks + = new HashMap<Integer, LinkedList<Operation>>(); + + /** Number of operations. */ + int operationCount; + + /** Sequential list of operations that happened in this process. */ + final List<Operation> operations = new ArrayList<Operation>(); + + /** List of past process names. */ + final List<String> nameHistory = new ArrayList<String>(); + + /** Constructs a new process. */ + Proc(Proc parent, int id) { + this.parent = parent; + this.id = id; + } + + /** Sets name of this process. */ + void setName(String name) { + if (!name.equals(this.name)) { + if (this.name != null) { + nameHistory.add(this.name); + } + this.name = name; + } + } + + /** + * Returns true if this process comes from the zygote. + */ + public boolean fromZygote() { + return parent != null && parent.name.equals("zygote") + && !name.equals("com.android.development"); + } + + /** + * Starts an operation. + * + * @param threadId thread the operation started in + * @param loadedClass class operation happened to + * @param time the operation started + */ + void startOperation(int threadId, LoadedClass loadedClass, long time, + Operation.Type type) { + Operation o = new Operation( + this, loadedClass, time, operationCount++, type); + operations.add(o); + + LinkedList<Operation> stack = stacks.get(threadId); + if (stack == null) { + stack = new LinkedList<Operation>(); + stacks.put(threadId, stack); + } + + if (!stack.isEmpty()) { + stack.getLast().subops.add(o); + } + + stack.add(o); + } + + /** + * Ends an operation. + * + * @param threadId thread the operation ended in + * @param loadedClass class operation happened to + * @param time the operation ended + */ + Operation endOperation(int threadId, String className, + LoadedClass loadedClass, long time) { + LinkedList<Operation> stack = stacks.get(threadId); + + if (stack == null || stack.isEmpty()) { + didNotStart(className); + return null; + } + + Operation o = stack.getLast(); + if (loadedClass != o.loadedClass) { + didNotStart(className); + return null; + } + + stack.removeLast(); + + o.endTimeNanos = time; + return o; + } + + /** + * Prints an error indicating that we saw the end of an operation but not + * the start. A bug in the logging framework which results in dropped logs + * causes this. + */ + private static void didNotStart(String name) { + System.err.println("Warning: An operation ended on " + name + + " but it never started!"); + } + + /** + * Prints this process tree to stdout. + */ + void print() { + print(""); + } + + /** + * Prints a child proc to standard out. + */ + private void print(String prefix) { + System.out.println(prefix + "id=" + id + ", name=" + name); + for (Proc child : children) { + child.print(prefix + " "); + } + } + + @Override + public String toString() { + return this.name; + } +} |