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.io.Serializable;
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.*;
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/**
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * A loaded class.
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass LoadedClass implements Serializable, Comparable<LoadedClass> {
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private static final long serialVersionUID = 0;
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Class name. */
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    final String name;
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Load operations. */
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    final List<Operation> loads = new ArrayList<Operation>();
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Static initialization operations. */
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    final List<Operation> initializations = new ArrayList<Operation>();
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Memory usage gathered by loading only this class in its own VM. */
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    MemoryUsage memoryUsage = MemoryUsage.NOT_AVAILABLE;
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Whether or not this class was loaded in the system class loader.
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    final boolean systemClass;
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Whether or not this class will be preloaded. */
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    boolean preloaded;
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Constructs a new class. */
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LoadedClass(String name, boolean systemClass) {
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        this.name = name;
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        this.systemClass = systemClass;
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void measureMemoryUsage() {
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        this.memoryUsage = MemoryUsage.forClass(name);
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int mlt = -1;
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Median time to load this class. */
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int medianLoadTimeMicros() {
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mlt != -1) {
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return mlt;
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mlt = calculateMedian(loads);
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int mit = -1;
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Median time to initialize this class. */
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int medianInitTimeMicros() {
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mit != -1) {
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return mit;
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mit = calculateMedian(initializations);
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int medianTimeMicros() {
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return medianInitTimeMicros() + medianLoadTimeMicros();
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Calculates the median duration for a list of operations. */
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private static int calculateMedian(List<Operation> operations) {
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int size = operations.size();
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (size == 0) {
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int[] times = new int[size];
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        for (int i = 0; i < size; i++) {
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            times[i] = operations.get(i).exclusiveTimeMicros();
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Arrays.sort(times);
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int middle = size / 2;
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (size % 2 == 1) {
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // Odd
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return times[middle];
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // Even -- average the two.
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return (times[middle - 1] + times[middle]) / 2;
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /** Returns names of processes that loaded this class. */
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Set<String> processNames() {
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Set<String> names = new HashSet<String>();
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        addProcessNames(loads, names);
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        addProcessNames(initializations, names);
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return names;
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private void addProcessNames(List<Operation> ops, Set<String> names) {
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        for (Operation operation : ops) {
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (operation.process.fromZygote()) {
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                names.add(operation.process.name);
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public int compareTo(LoadedClass o) {
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return name.compareTo(o.name);
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public String toString() {
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return name;
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
131