diff options
37 files changed, 133 insertions, 3053 deletions
diff --git a/dexdump/Android.mk b/dexdump/Android.mk index 9aa4ae913..d9a06d136 100644 --- a/dexdump/Android.mk +++ b/dexdump/Android.mk @@ -43,6 +43,7 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_MODULE_TAGS := optional LOCAL_LDLIBS += LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) @@ -53,6 +54,7 @@ LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries) LOCAL_SHARED_LIBRARIES := libutils LOCAL_MODULE_TAGS := optional LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_STATIC_LIBRARY) endif # !SDK_ONLY @@ -69,11 +71,12 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(dexdump_src_files) LOCAL_C_INCLUDES := $(dexdump_c_includes) LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries) liblog libutils - ifneq ($(strip $(USE_MINGW)),) LOCAL_STATIC_LIBRARIES += libz else LOCAL_LDLIBS += -lpthread -lz endif - +# TODO: Move dexdump from libdex to libart and lose the 32-bit limitation. +LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_HOST_EXECUTABLE) diff --git a/dexlist/Android.mk b/dexlist/Android.mk index 19b52d06d..4d4a709f0 100644 --- a/dexlist/Android.mk +++ b/dexlist/Android.mk @@ -35,6 +35,7 @@ LOCAL_SHARED_LIBRARIES := libcutils libz libutils LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries) LOCAL_LDLIBS += LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk #include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) @@ -44,4 +45,7 @@ LOCAL_SRC_FILES := $(dexdump_src_files) LOCAL_C_INCLUDES := $(dexdump_c_includes) LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries) libcutils liblog libutils LOCAL_LDLIBS += -lpthread -lz +# TODO: Move dexlist from libdex to libart and lose the 32-bit limitation. +LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_HOST_EXECUTABLE) diff --git a/docs/hello-world.html b/docs/hello-world.html index 7491a2821..d988e2f4b 100644 --- a/docs/hello-world.html +++ b/docs/hello-world.html @@ -88,127 +88,6 @@ See <a href="debugger.html">Dalvik Debugger Support</a> for more information about using debuggers with Dalvik. - -<h2>Working with the desktop build</h2> - -<!-- largely lifted from -http://groups.google.com/group/android-porting/browse_thread/thread/ab553116dbc960da/29167c58b3b49051#29167c58b3b49051 ---> - -<p> -The Dalvik VM can also be used directly on the desktop. This is somewhat -more complicated however, because you won't have certain things set up in -your environment, and several native code libraries are required to support -the core Dalvik libs. -</p><p> -Start with: - -<pre> - . build/envsetup.sh - lunch sim-eng -</pre> - -You should see something like: - -<pre> - ============================================ - TARGET_PRODUCT=sim - TARGET_BUILD_VARIANT=eng - TARGET_SIMULATOR=true - TARGET_BUILD_TYPE=debug - TARGET_ARCH=x86 - HOST_ARCH=x86 - HOST_OS=linux - HOST_BUILD_TYPE=release - BUILD_ID= - ============================================ -</pre> - -</p></p> -This configures you to build for the desktop, linking against glibc. -This mode is NOT recommended for anything but experimental use. It -may go away in the future. -</p></p> -You may see <code>TARGET_BUILD_TYPE=release</code> or <code>=debug</code> -or possibly nothing there at all. You may want to replace the -<code>lunch</code> command with -<code>choosecombo Simulator debug sim eng</code>. -</p></p> -Build the world (add a <code>-j4</code> if you have multiple cores): - -<pre> - make -</pre> - -</p></p> -When that completes, you have a working dalvikm on your desktop -machine: - -<pre> - % dalvikvm - E/dalvikvm(19521): ERROR: must specify non-'.' bootclasspath - W/dalvikvm(19521): JNI_CreateJavaVM failed - Dalvik VM init failed (check log file) -</pre> - -</p></p> -To actually do something, you need to specify the bootstrap class path -and give it a place to put DEX data that it uncompresses from jar -files. You can do that with a script like this: - -<blockquote><pre> -#!/bin/sh - -# base directory, at top of source tree; replace with absolute path -base=`pwd` - -# configure root dir of interesting stuff -root=$base/out/debug/host/linux-x86/product/sim/system -export ANDROID_ROOT=$root - -# configure bootclasspath -bootpath=$root/framework -export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar - -# this is where we create the dalvik-cache directory; make sure it exists -export ANDROID_DATA=/tmp/dalvik_$USER -mkdir -p $ANDROID_DATA/dalvik-cache - -exec dalvikvm $@ -</pre></blockquote> - -</p></p> -The preparation with <code>dx</code> is the same as before: - -<pre> - % cat > Foo.java - class Foo { public static void main(String[] args) { - System.out.println("Hello, world"); - } } - (ctrl-D) - % javac Foo.java - % dx --dex --output=foo.jar Foo.class - % ./rund -cp foo.jar Foo - Hello, world -</pre> - -As above, you can get some info about valid arguments like this: - -<pre> - % ./rund -help -</pre> - -</p></p> -This also shows what options the VM was configured with. The sim "debug" -build has all sorts of additional assertions and checks enabled, -which slows the VM down, but since this is just for experiments it -doesn't matter. - -</p></p> -All of the above applies to x86 Linux. Anything else will likely -require a porting effort. If libffi supports your system, the amount of -work required should be minor. - </p></p> <address>Copyright © 2009 The Android Open Source Project</address> diff --git a/dx/tests/113-old-style-inner-class/run b/dx/tests/113-old-style-inner-class/run index c93661f95..ecb64977e 100644 --- a/dx/tests/113-old-style-inner-class/run +++ b/dx/tests/113-old-style-inner-class/run @@ -16,7 +16,7 @@ # We compile for a 1.4 target to suppress the use of EnclosingMethod # attributes. -${JAVAC} -source 1.4 -target 1.4 -d . Blort.java +${JAVAC} -source 1.4 -target 1.4 -d . Blort.java &> /dev/null # We expect there to be two warning lines, one for each of the inner classes. dx --debug --dex *.class 2>&1 | awk '/^warning:/ { print $1 }' diff --git a/dx/tests/118-find-usages/expected.txt b/dx/tests/118-find-usages/expected.txt index aca2bf165..9b1111021 100644 --- a/dx/tests/118-find-usages/expected.txt +++ b/dx/tests/118-find-usages/expected.txt @@ -1,9 +1,9 @@ StreamTokenizer.nval -LFoo;.readStreamTokenizerNval: field reference (iget-wide) -LFoo;.writeStreamTokenizerNval: field reference (iput-wide) +LFoo;.readStreamTokenizerNval: field reference D.nval (iget-wide) +LFoo;.writeStreamTokenizerNval: field reference D.nval (iput-wide) ArrayList.remove() -LFoo;.callArrayListRemoveIndex: method reference (invoke-virtual) -LFoo;.callArrayListRemoveValue: method reference (invoke-virtual) +LFoo;.callArrayListRemoveIndex: method reference Ljava/util/ArrayList;.remove(I) (invoke-virtual) +LFoo;.callArrayListRemoveValue: method reference Ljava/util/ArrayList;.remove(Ljava/lang/Object;) (invoke-virtual) Collection.remove() String.valueOf() -LFoo;.callStringValueOf: method reference (invoke-static) +LFoo;.callStringValueOf: method reference Ljava/lang/String;.valueOf(I) (invoke-static) diff --git a/dx/tests/124-multidex-option-no-overflow/run b/dx/tests/124-multidex-option-no-overflow/run index 4cd14bc5e..d9097fc86 100644 --- a/dx/tests/124-multidex-option-no-overflow/run +++ b/dx/tests/124-multidex-option-no-overflow/run @@ -17,7 +17,7 @@ # Stop if something fails. set -e -# Write out files with 25500 total static fields, instance fields, and methods +# Write out files with many static fields, instance fields, and methods but # not exceeding the dex format's limits. mkdir src awk ' @@ -29,7 +29,7 @@ BEGIN { function writeFileField(name, type) { fileName = "src/" name ".java"; printf("public class %s {\n", name) > fileName; - for (i = 1; i <= 25500; i++) { + for (i = 1; i <= 21000; i++) { printf(" %s%d;\n", type, i) > fileName; } printf("}\n") > fileName; @@ -37,7 +37,7 @@ function writeFileField(name, type) { function writeFileMethod(name) { fileName = "src/" name ".java"; printf("public class %s {\n", name) > fileName; - for (i = 1; i <= 25500; i++) { + for (i = 1; i <= 32000; i++) { printf(" public void meth%d() { }\n", i) > fileName; } printf("}\n") > fileName; diff --git a/dx/tests/127-merge-stress/run b/dx/tests/127-merge-stress/run index c8308cf17..d66beb47d 100644..100755 --- a/dx/tests/127-merge-stress/run +++ b/dx/tests/127-merge-stress/run @@ -19,11 +19,21 @@ prog=`which dx` progdir=`dirname "${prog}"` dxjar=$progdir/../framework/dx.jar -# Find dex files in tree +# Find dex files in the tree dexes=`find $ANDROID_BUILD_TOP/out -name '*.dex' -printf '%p '` dexesinjars=`find $ANDROID_BUILD_TOP/libcore $ANDROID_BUILD_TOP/out -name '*.jar' -exec sh -c 'unzip -l "{}" 2>/dev/null | grep -q classes.dex ' \; -printf '%p '` dexesinapks=`find $ANDROID_BUILD_TOP/libcore $ANDROID_BUILD_TOP/out -name '*.apk' -exec sh -c 'unzip -l "{}" 2>/dev/null | grep -q classes.dex ' \; -printf '%p '` +# Select only the valid dex files +validdexes="" +for dex in $dexes $dexesinjars $dexesinapks; do + dexdump -c $dex &> /dev/null + if [ $? -eq 0 ]; then + validdexes="$validdexes $dex" + fi +done + +# Compile and run java merging test $JAVAC -cp $dxjar -d . com/android/dx/merge/MergeTest.java -java -cp .:$dxjar com.android.dx.merge.MergeTest $dexes $dexesinjars $dexesinapks >/dev/null +java -cp .:$dxjar com.android.dx.merge.MergeTest $validdexes >/dev/null diff --git a/hit/samples/android.hprof b/hit/samples/android.hprof Binary files differdeleted file mode 100644 index bb8d2e0f2..000000000 --- a/hit/samples/android.hprof +++ /dev/null diff --git a/hit/src/com/android/hit/ArrayInstance.java b/hit/src/com/android/hit/ArrayInstance.java deleted file mode 100644 index 42e880357..000000000 --- a/hit/src/com/android/hit/ArrayInstance.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.util.Set; - -public class ArrayInstance extends Instance { - private int mType; - private int mNumEntries; - private byte[] mData; - - public ArrayInstance(long id, StackTrace stack, int type, int numEntries, - byte[] data) { - mId = id; - mStack = stack; - mType = type; - mNumEntries = numEntries; - mData = data; - } - - public final void resolveReferences(State state) { - if (mType != Types.OBJECT) { - return; - } - - /* - * mData holds a stream of object instance ids - * Spin through them all and list ourselves as a reference holder. - */ - int idSize = Types.getTypeSize(mType); - final int N = mNumEntries; - - ByteArrayInputStream bais = new ByteArrayInputStream(mData); - DataInputStream dis = new DataInputStream(bais); - - for (int i = 0; i < N; i++) { - long id; - - try { - if (idSize == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - Instance instance = state.findReference(id); - - if (instance != null) { - instance.addParent(this); - } - } catch (java.io.IOException e) { - e.printStackTrace(); - } - } - } - - @Override - public final int getSize() { - return mData.length; - } - - @Override - public final void visit(Set<Instance> resultSet, Filter filter) { - // If we're in the set then we and our children have been visited - if (resultSet.contains(this)) { - return; - } - - if (null != filter) { - if (filter.accept(this)) { - resultSet.add(this); - } - } else { - resultSet.add(this); - } - - if (mType != Types.OBJECT) { - return; - } - - /* - * mData holds a stream of object instance ids - * Spin through them all and visit them - */ - int idSize = Types.getTypeSize(mType); - final int N = mNumEntries; - - ByteArrayInputStream bais = new ByteArrayInputStream(mData); - DataInputStream dis = new DataInputStream(bais); - State state = mHeap.mState; - - for (int i = 0; i < N; i++) { - long id; - - try { - if (idSize == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - Instance instance = state.findReference(id); - - if (instance != null) { - instance.visit(resultSet, filter); - } - } catch (java.io.IOException e) { - e.printStackTrace(); - } - } - } - - @Override - public final String getTypeName() { - return Types.getTypeName(mType) + "[" + mNumEntries + "]"; - } - - public final String toString() { - return String.format("%s@0x08x", getTypeName(), mId); - } - - @Override - public String describeReferenceTo(long referent) { - // If this isn't an object array then we can't refer to an object - if (mType != Types.OBJECT) { - return super.describeReferenceTo(referent); - } - - int idSize = Types.getTypeSize(mType); - final int N = mNumEntries; - int numRefs = 0; - StringBuilder result = new StringBuilder("Elements ["); - ByteArrayInputStream bais = new ByteArrayInputStream(mData); - DataInputStream dis = new DataInputStream(bais); - - /* - * Spin through all the objects and build up a string describing - * all of the array elements that refer to the target object. - */ - for (int i = 0; i < N; i++) { - long id; - - try { - if (idSize == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - if (id == referent) { - numRefs++; - - if (numRefs > 1) { - result.append(", "); - } - - result.append(i); - } - } catch (java.io.IOException e) { - e.printStackTrace(); - } - } - - if (numRefs == 0) { - return super.describeReferenceTo(referent); - } - - result.append("]"); - - return result.toString(); - } -} diff --git a/hit/src/com/android/hit/ClassInstance.java b/hit/src/com/android/hit/ClassInstance.java deleted file mode 100644 index 086976960..000000000 --- a/hit/src/com/android/hit/ClassInstance.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Set; - -public class ClassInstance extends Instance { - private byte[] mFieldValues; - - public ClassInstance(long id, StackTrace stack, long classId) { - mId = id; - mStack = stack; - mClassId = classId; - } - - public final void loadFieldData(DataInputStream in, int numBytes) - throws IOException { - mFieldValues = new byte[numBytes]; - in.readFully(mFieldValues); - } - - @Override - public void resolveReferences(State state) { - ClassObj isa = mHeap.mState.findClass(mClassId); - - resolve(state, isa, isa.mStaticFieldTypes, isa.mStaticFieldValues); - resolve(state, isa, isa.mFieldTypes, mFieldValues); - } - - private void resolve(State state, ClassObj isa, int[] types, - byte[] values) { - ByteArrayInputStream bais = new ByteArrayInputStream(values); - DataInputStream dis = new DataInputStream(bais); - final int N = types.length; - - /* - * Spin through the list of fields, find all object references, - * and list ourselves as a reference holder. - */ - try { - for (int i = 0; i < N; i++) { - int type = types[i]; - int size = Types.getTypeSize(type); - - if (type == Types.OBJECT) { - long id; - - if (size == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - Instance instance = state.findReference(id); - - if (instance != null) { - instance.addParent(this); - } - } else { - dis.skipBytes(size); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public final int getSize() { - ClassObj isa = mHeap.mState.findClass(mClassId); - - return isa.getSize(); - } - - @Override - public final void visit(Set<Instance> resultSet, Filter filter) { - if (resultSet.contains(this)) { - return; - } - - if (filter != null) { - if (filter.accept(this)) { - resultSet.add(this); - } - } else { - resultSet.add(this); - } - - State state = mHeap.mState; - ClassObj isa = state.findClass(mClassId); - int[] types = isa.mFieldTypes; - ByteArrayInputStream bais = new ByteArrayInputStream(mFieldValues); - DataInputStream dis = new DataInputStream(bais); - final int N = types.length; - - /* - * Spin through the list of fields, find all object references, - * and list ourselves as a reference holder. - */ - try { - for (int i = 0; i < N; i++) { - int type = types[i]; - int size = Types.getTypeSize(type); - - if (type == Types.OBJECT) { - long id; - - if (size == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - Instance instance = state.findReference(id); - - if (instance != null) { - instance.visit(resultSet, filter); - } - } else { - dis.skipBytes(size); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public final String getTypeName() { - ClassObj theClass = mHeap.mState.findClass(mClassId); - - return theClass.mClassName; - } - - public final String toString() { - return String.format("%s@0x%08x", getTypeName(), mId); - } - - @Override - public String describeReferenceTo(long referent) { - ClassObj isa = mHeap.mState.findClass(mClassId); - int[] types = isa.mFieldTypes; - String[] fieldNames = isa.mFieldNames; - ByteArrayInputStream bais = new ByteArrayInputStream(mFieldValues); - DataInputStream dis = new DataInputStream(bais); - final int N = types.length; - StringBuilder result = new StringBuilder("Referenced in field(s):"); - int numReferences = 0; - - /* - * Spin through the list of fields, add info about the field - * references to the output text. - */ - try { - for (int i = 0; i < N; i++) { - int type = types[i]; - int size = Types.getTypeSize(type); - - if (type == Types.OBJECT) { - long id; - - if (size == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - if (id == referent) { - numReferences++; - result.append("\n "); - result.append(fieldNames[i]); - } - } else { - dis.skipBytes(size); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - - /* - * TODO: perform a similar loop over the static fields of isa - */ - - if (numReferences == 0) { - return super.describeReferenceTo(referent); - } - - return result.toString(); - } -} diff --git a/hit/src/com/android/hit/ClassObj.java b/hit/src/com/android/hit/ClassObj.java deleted file mode 100644 index 1e3ac280d..000000000 --- a/hit/src/com/android/hit/ClassObj.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -public class ClassObj extends Instance implements Comparable<ClassObj> { - String mClassName; - long mSuperclassId; - - String[] mFieldNames; - int[] mFieldTypes; - - String[] mStaticFieldNames; - int[] mStaticFieldTypes; - byte[] mStaticFieldValues; - - ArrayList<Instance> mInstances = new ArrayList<Instance>(); - Set<ClassObj> mSubclasses = new HashSet<ClassObj>(); - - int mSize; - - public ClassObj(long id, StackTrace stack, String className) { - mId = id; - mStack = stack; - mClassName = className; - } - - @Override - public final void resolveReferences(State state) { - ByteArrayInputStream bais = - new ByteArrayInputStream(mStaticFieldValues); - DataInputStream dis = new DataInputStream(bais); - int[] types = mStaticFieldTypes; - final int N = types.length; - - /* - * Spin through the list of static fields, find all object references, - * and list ourselves as a reference holder. Also add them to - * the list of root objects. - */ - try { - for (int i = 0; i < N; i++) { - int type = types[i]; - int size = Types.getTypeSize(type); - - if (type == Types.OBJECT) { - long id; - - if (size == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - RootObj root = new RootObj(RootType.JAVA_STATIC, id); - - if (id == 0) { - root.mComment = String.format( - "Static field %s:%s null", - mClassName, - mStaticFieldNames[i]); - } else { - Instance instance = state.findReference(id); - - instance.addParent(this); - - root.mComment = String.format( - "Static field %s:%s %s [%s] 0x%08x", - mClassName, - mStaticFieldNames[i], - instance.getTypeName(), - instance.mHeap.mName, - id); - } - - mHeap.addRoot(root); - } else { - dis.skipBytes(size); - } - } - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - - // Lastly, add ourself as a subclass of our superclass - if (mSuperclassId != 0) { - ClassObj superclass = state.findClass(mSuperclassId); - - superclass.addSubclass(this); - } - } - - public final void addSubclass(ClassObj subclass) { - mSubclasses.add(subclass); - } - - public final void dumpSubclasses() { - for (ClassObj subclass: mSubclasses) { - System.out.println(" " + subclass.mClassName); - } - } - - public final String toString() { - return mClassName.replace('/', '.'); - } - - public final void addInstance(Instance instance) { - mInstances.add(instance); - } - - public final void setSuperclassId(long id) { - mSuperclassId = id; - } - - public final void setFieldNames(String[] names) { - mFieldNames = names; - } - - public final void setFieldTypes(int[] types) { - mFieldTypes = types; - } - - public final void setStaticFieldNames(String[] names) { - mStaticFieldNames = names; - } - - public final void setStaticFieldTypes(int[] types) { - mStaticFieldTypes = types; - } - - public final void setStaticFieldValues(byte[] values) { - mStaticFieldValues = values; - } - - public final void dump() { - System.out.println("+---------- ClassObj dump for: " + mClassName); - - System.out.println("+----- Static fields"); - - for (int i = 0; i < mStaticFieldNames.length; i++) { - System.out.println(mStaticFieldNames[i] + ": " - + mStaticFieldTypes[i]); - } - - System.out.println("+----- Instance fields"); - - for (int i = 0; i < mFieldNames.length; i++) { - System.out.println(mFieldNames[i] + ": " + mFieldTypes[i]); - } - } - - @Override - public final String getTypeName() { - return "class " + mClassName; - } - - @Override - public final void visit(Set<Instance> resultSet, Filter filter) { - if (resultSet.contains(this)) { - return; - } - - if (filter != null) { - if (filter.accept(this)) { - resultSet.add(this); - } - } else { - resultSet.add(this); - } - - ByteArrayInputStream bais = - new ByteArrayInputStream(mStaticFieldValues); - DataInputStream dis = new DataInputStream(bais); - int[] types = mStaticFieldTypes; - final int N = types.length; - State state = mHeap.mState; - - /* - * Spin through the list of static fields, find all object references, - * and visit them. - */ - try { - for (int i = 0; i < N; i++) { - int type = types[i]; - int size = Types.getTypeSize(type); - - if (type == Types.OBJECT) { - long id; - - if (size == 4) { - id = dis.readInt(); - } else { - id = dis.readLong(); - } - - Instance instance = state.findReference(id); - - if (instance != null) { - instance.visit(resultSet, filter); - } - } else { - dis.skipBytes(size); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public final int compareTo(ClassObj o) { - return mClassName.compareTo(o.mClassName); - } - - public final boolean equals(Object o) { - if (! (o instanceof ClassObj)) { - return false; - } - - return 0 == compareTo((ClassObj) o); - } -} diff --git a/hit/src/com/android/hit/Heap.java b/hit/src/com/android/hit/Heap.java deleted file mode 100644 index 37b15ddc5..000000000 --- a/hit/src/com/android/hit/Heap.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.util.ArrayList; -import java.util.HashMap; - -public class Heap { - String mName; - - // List of individual stack frames - HashMap<Long, StackFrame> mFrames = new HashMap<Long, StackFrame>(); - - // List stack traces, which are lists of stack frames - HashMap<Integer, StackTrace> mTraces = new HashMap<Integer, StackTrace>(); - - // Root objects such as interned strings, jni locals, etc - ArrayList<RootObj> mRoots = new ArrayList<RootObj>(); - - // List of threads - HashMap<Integer, ThreadObj> mThreads = new HashMap<Integer, ThreadObj>(); - - // Class definitions - HashMap<Long, ClassObj> mClassesById = new HashMap<Long, ClassObj>(); - HashMap<String, ClassObj> mClassesByName = new HashMap<String, ClassObj>(); - - // List of instances of above class definitions - HashMap<Long, Instance> mInstances = new HashMap<Long, Instance>(); - - // The super-state that this heap is part of - State mState; - - public Heap(String name) { - mName = name; - } - - public final void addStackFrame(StackFrame theFrame) { - mFrames.put(theFrame.mId, theFrame); - } - - public final StackFrame getStackFrame(long id) { - return mFrames.get(id); - } - - public final void addStackTrace(StackTrace theTrace) { - mTraces.put(theTrace.mSerialNumber, theTrace); - } - - public final StackTrace getStackTrace(int traceSerialNumber) { - return mTraces.get(traceSerialNumber); - } - - public final StackTrace getStackTraceAtDepth(int traceSerialNumber, - int depth) { - StackTrace trace = mTraces.get(traceSerialNumber); - - if (trace != null) { - trace = trace.fromDepth(depth); - } - - return trace; - } - - public final void addRoot(RootObj root) { - root.mIndex = mRoots.size(); - mRoots.add(root); - } - - public final void addThread(ThreadObj thread, int serialNumber) { - mThreads.put(serialNumber, thread); - } - - public final ThreadObj getThread(int serialNumber) { - return mThreads.get(serialNumber); - } - - public final void addInstance(long id, Instance instance) { - mInstances.put(id, instance); - } - - public final Instance getInstance(long id) { - return mInstances.get(id); - } - - public final void addClass(long id, ClassObj theClass) { - mClassesById.put(id, theClass); - mClassesByName.put(theClass.mClassName, theClass); - } - - public final ClassObj getClass(long id) { - return mClassesById.get(id); - } - - public final ClassObj getClass(String name) { - return mClassesByName.get(name); - } - - public final void dumpInstanceCounts() { - for (ClassObj theClass: mClassesById.values()) { - int count = theClass.mInstances.size(); - - if (count > 0) { - System.out.println(theClass + ": " + count); - } - } - } - - public final void dumpSubclasses() { - for (ClassObj theClass: mClassesById.values()) { - int count = theClass.mSubclasses.size(); - - if (count > 0) { - System.out.println(theClass); - theClass.dumpSubclasses(); - } - } - } - - public final void dumpSizes() { - for (ClassObj theClass: mClassesById.values()) { - int size = 0; - - for (Instance instance: theClass.mInstances) { - size += instance.getCompositeSize(); - } - - if (size > 0) { - System.out.println(theClass + ": base " + theClass.getSize() - + ", composite " + size); - } - } - } - - /* - * Spin through all of the class instances and link them to their - * parent class definition objects. Then have each instance resolve - * its own internal object references. - */ - public final void resolveInstanceRefs(State state) { - for (Instance instance : mInstances.values()) { - ClassObj theClass = mClassesById.get(instance.mClassId); - - if (theClass == null) { - continue; - } - - String name = theClass.mClassName; - String superclassName = "none"; - ClassObj superClass = mClassesById.get(theClass.mSuperclassId); - - if (superClass != null) { - superclassName = superClass.mClassName; - } - - theClass.addInstance(instance); - instance.resolveReferences(state); - } - } - - public final void resolveClassStatics(State state) { - for (ClassObj theClass: mClassesById.values()) { - theClass.resolveReferences(state); - } - } - - public final void resolveRoots(State state) { - for (RootObj root: mRoots) { - root.resolveReferences(state); - } - } -} diff --git a/hit/src/com/android/hit/HprofParser.java b/hit/src/com/android/hit/HprofParser.java deleted file mode 100644 index 98fef1e12..000000000 --- a/hit/src/com/android/hit/HprofParser.java +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.InputStream; -import java.io.EOFException; -import java.io.IOException; -import java.util.HashMap; - -public class HprofParser -{ - private static final int STRING_IN_UTF8 = 0x01; - private static final int LOAD_CLASS = 0x02; - private static final int UNLOAD_CLASS = 0x03; // unused - private static final int STACK_FRAME = 0x04; - private static final int STACK_TRACE = 0x05; - private static final int ALLOC_SITES = 0x06; // unused - private static final int HEAP_SUMMARY = 0x07; - private static final int START_THREAD = 0x0a; // unused - private static final int END_THREAD = 0x0b; // unused - private static final int HEAP_DUMP = 0x0c; - private static final int HEAP_DUMP_SEGMENT = 0x1c; - private static final int HEAP_DUMP_END = 0x2c; - private static final int CPU_SAMPLES = 0x0d; // unused - private static final int CONTROL_SETTINGS = 0x0e; // unused - - private static final int ROOT_UNKNOWN = 0xff; - private static final int ROOT_JNI_GLOBAL = 0x01; - private static final int ROOT_JNI_LOCAL = 0x02; - private static final int ROOT_JAVA_FRAME = 0x03; - private static final int ROOT_NATIVE_STACK = 0x04; - private static final int ROOT_STICKY_CLASS = 0x05; - private static final int ROOT_THREAD_BLOCK = 0x06; - private static final int ROOT_MONITOR_USED = 0x07; - private static final int ROOT_THREAD_OBJECT = 0x08; - private static final int ROOT_CLASS_DUMP = 0x20; - private static final int ROOT_INSTANCE_DUMP = 0x21; - private static final int ROOT_OBJECT_ARRAY_DUMP = 0x22; - private static final int ROOT_PRIMITIVE_ARRAY_DUMP = 0x23; - - /** - * Android format addition - * - * Specifies information about which heap certain objects came from. - * When a sub-tag of this type appears in a HPROF_HEAP_DUMP or - * HPROF_HEAP_DUMP_SEGMENT record, entries that follow it will be - * associated with the specified heap. The HEAP_DUMP_INFO data is reset - * at the end of the HEAP_DUMP[_SEGMENT]. Multiple HEAP_DUMP_INFO entries - * may appear in a single HEAP_DUMP[_SEGMENT]. - * - * Format: - * u1: Tag value (0xFE) - * u4: heap ID - * ID: heap name string ID - */ - private static final int ROOT_HEAP_DUMP_INFO = 0xfe; - private static final int ROOT_INTERNED_STRING = 0x89; - private static final int ROOT_FINALIZING = 0x8a; - private static final int ROOT_DEBUGGER = 0x8b; - private static final int ROOT_REFERENCE_CLEANUP = 0x8c; - private static final int ROOT_VM_INTERNAL = 0x8d; - private static final int ROOT_JNI_MONITOR = 0x8e; - private static final int ROOT_UNREACHABLE = 0x90; - private static final int ROOT_PRIMITIVE_ARRAY_NODATA= 0xc3; - - DataInputStream mInput; - int mIdSize; - State mState; - - byte[] mFieldBuffer = new byte[8]; - - /* - * These are only needed while parsing so are not kept as part of the - * heap data. - */ - HashMap<Long, String> mStrings = new HashMap<Long, String>(); - HashMap<Long, String> mClassNames = new HashMap<Long, String>(); - - public HprofParser(DataInputStream in) { - mInput = in; - } - - public final State parse() { - State state = new State(); - mState = state; - - try { - String s = readNullTerminatedString(); - DataInputStream in = mInput; - - mIdSize = in.readInt(); - Types.setIdSize(mIdSize); - - in.readLong(); // Timestamp, ignored for now - - while (true) { - int tag = in.readUnsignedByte(); - int timestamp = in.readInt(); - int length = in.readInt(); - - switch (tag) { - case STRING_IN_UTF8: - loadString(length - 4); - break; - - case LOAD_CLASS: - loadClass(); - break; - - case STACK_FRAME: - loadStackFrame(); - break; - - case STACK_TRACE: - loadStackTrace(); - break; - - case HEAP_DUMP: - loadHeapDump(length); - mState.setToDefaultHeap(); - break; - - case HEAP_DUMP_SEGMENT: - loadHeapDump(length); - mState.setToDefaultHeap(); - break; - - default: - skipFully(length); - } - - } - } catch (EOFException eof) { - // this is fine - } catch (Exception e) { - e.printStackTrace(); - } - - mState.resolveReferences(); - - return state; - } - - private String readNullTerminatedString() throws IOException { - StringBuilder s = new StringBuilder(); - DataInputStream in = mInput; - - for (int c = in.read(); c != 0; c = in.read()) { - s.append((char) c); - } - - return s.toString(); - } - - private long readId() throws IOException { - switch (mIdSize) { - case 1: return mInput.readUnsignedByte(); - case 2: return mInput.readUnsignedShort(); - case 4: return ((long) mInput.readInt()) & 0x00000000ffffffffL; - case 8: return mInput.readLong(); - } - - throw new IllegalArgumentException("ID Length must be 1, 2, 4, or 8"); - } - - private String readUTF8(int length) throws IOException { - byte[] b = new byte[length]; - - mInput.read(b); - - return new String(b, "utf-8"); - } - - private void loadString(int length) throws IOException { - long id = readId(); - String string = readUTF8(length); - - mStrings.put(id, string); - } - - private void loadClass() throws IOException { - DataInputStream in = mInput; - int serial = in.readInt(); - long id = readId(); - int stackTrace = in.readInt(); // unused - String name = mStrings.get(readId()); - - mClassNames.put(id, name); - } - - private void loadStackFrame() throws IOException { - long id = readId(); - String methodName = mStrings.get(readId()); - String methodSignature = mStrings.get(readId()); - String sourceFile = mStrings.get(readId()); - int serial = mInput.readInt(); - int lineNumber = mInput.readInt(); - - StackFrame frame = new StackFrame(id, methodName, methodSignature, - sourceFile, serial, lineNumber); - - mState.addStackFrame(frame); - } - - private void loadStackTrace() throws IOException { - int serialNumber = mInput.readInt(); - int threadSerialNumber = mInput.readInt(); - final int numFrames = mInput.readInt(); - StackFrame[] frames = new StackFrame[numFrames]; - - for (int i = 0; i < numFrames; i++) { - frames[i] = mState.getStackFrame(readId()); - } - - StackTrace trace = new StackTrace(serialNumber, threadSerialNumber, - frames); - - mState.addStackTrace(trace); - } - - private void loadHeapDump(int length) throws IOException { - DataInputStream in = mInput; - - while (length > 0) { - int tag = in.readUnsignedByte(); - length--; - - switch (tag) { - case ROOT_UNKNOWN: - length -= loadBasicObj(RootType.UNKNOWN); - break; - - case ROOT_JNI_GLOBAL: - length -= loadBasicObj(RootType.NATIVE_STATIC); - readId(); // ignored - length -= mIdSize; - break; - - case ROOT_JNI_LOCAL: - length -= loadJniLocal(); - break; - - case ROOT_JAVA_FRAME: - length -= loadJavaFrame(); - break; - - case ROOT_NATIVE_STACK: - length -= loadNativeStack(); - break; - - case ROOT_STICKY_CLASS: - length -= loadBasicObj(RootType.SYSTEM_CLASS); - break; - - case ROOT_THREAD_BLOCK: - length -= loadThreadBlock(); - break; - - case ROOT_MONITOR_USED: - length -= loadBasicObj(RootType.BUSY_MONITOR); - break; - - case ROOT_THREAD_OBJECT: - length -= loadThreadObject(); - break; - - case ROOT_CLASS_DUMP: - length -= loadClassDump(); - break; - - case ROOT_INSTANCE_DUMP: - length -= loadInstanceDump(); - break; - - case ROOT_OBJECT_ARRAY_DUMP: - length -= loadObjectArrayDump(); - break; - - case ROOT_PRIMITIVE_ARRAY_DUMP: - length -= loadPrimitiveArrayDump(); - break; - - case ROOT_PRIMITIVE_ARRAY_NODATA: - System.err.println("+--- PRIMITIVE ARRAY NODATA DUMP"); - length -= loadPrimitiveArrayDump(); - - throw new IllegalArgumentException( - "Don't know how to load a nodata array"); - - case ROOT_HEAP_DUMP_INFO: - int heapId = mInput.readInt(); - long heapNameId = readId(); - String heapName = mStrings.get(heapNameId); - - mState.setHeapTo(heapId, heapName); - length -= 4 + mIdSize; - break; - - case ROOT_INTERNED_STRING: - length -= loadBasicObj(RootType.INTERNED_STRING); - break; - - case ROOT_FINALIZING: - length -= loadBasicObj(RootType.FINALIZING); - break; - - case ROOT_DEBUGGER: - length -= loadBasicObj(RootType.DEBUGGER); - break; - - case ROOT_REFERENCE_CLEANUP: - length -= loadBasicObj(RootType.REFERENCE_CLEANUP); - break; - - case ROOT_VM_INTERNAL: - length -= loadBasicObj(RootType.VM_INTERNAL); - break; - - case ROOT_JNI_MONITOR: - length -= loadJniMonitor(); - break; - - case ROOT_UNREACHABLE: - length -= loadBasicObj(RootType.UNREACHABLE); - break; - - default: - throw new IllegalArgumentException( - "loadHeapDump loop with unknown tag " + tag - + " with " + mInput.available() - + " bytes possibly remaining"); - } - } - } - - private int loadJniLocal() throws IOException { - long id = readId(); - int threadSerialNumber = mInput.readInt(); - int stackFrameNumber = mInput.readInt(); - ThreadObj thread = mState.getThread(threadSerialNumber); - StackTrace trace = mState.getStackTraceAtDepth(thread.mStackTrace, - stackFrameNumber); - RootObj root = new RootObj(RootType.NATIVE_LOCAL, id, - threadSerialNumber, trace); - - root.setHeap(mState.mCurrentHeap); - mState.addRoot(root); - - return mIdSize + 4 + 4; - } - - private int loadJavaFrame() throws IOException { - long id = readId(); - int threadSerialNumber = mInput.readInt(); - int stackFrameNumber = mInput.readInt(); - ThreadObj thread = mState.getThread(threadSerialNumber); - StackTrace trace = mState.getStackTraceAtDepth(thread.mStackTrace, - stackFrameNumber); - RootObj root = new RootObj(RootType.JAVA_LOCAL, id, threadSerialNumber, - trace); - - root.setHeap(mState.mCurrentHeap); - mState.addRoot(root); - - return mIdSize + 4 + 4; - } - - private int loadNativeStack() throws IOException { - long id = readId(); - int threadSerialNumber = mInput.readInt(); - ThreadObj thread = mState.getThread(threadSerialNumber); - StackTrace trace = mState.getStackTrace(thread.mStackTrace); - RootObj root = new RootObj(RootType.NATIVE_STACK, id, - threadSerialNumber, trace); - - root.setHeap(mState.mCurrentHeap); - mState.addRoot(root); - - return mIdSize + 4; - } - - private int loadBasicObj(RootType type) throws IOException { - long id = readId(); - RootObj root = new RootObj(type, id); - - root.setHeap(mState.mCurrentHeap); - mState.addRoot(root); - - return mIdSize; - } - - private int loadThreadBlock() throws IOException { - long id = readId(); - int threadSerialNumber = mInput.readInt(); - ThreadObj thread = mState.getThread(threadSerialNumber); - StackTrace stack = mState.getStackTrace(thread.mStackTrace); - RootObj root = new RootObj(RootType.THREAD_BLOCK, id, - threadSerialNumber, stack); - - root.setHeap(mState.mCurrentHeap); - mState.addRoot(root); - - return mIdSize + 4; - } - - private int loadThreadObject() throws IOException { - long id = readId(); - int threadSerialNumber = mInput.readInt(); - int stackSerialNumber = mInput.readInt(); - ThreadObj thread = new ThreadObj(id, stackSerialNumber); - - mState.addThread(thread, threadSerialNumber); - - return mIdSize + 4 + 4; - } - - private int loadClassDump() throws IOException { - int bytesRead = 0; - DataInputStream in = mInput; - long id = readId(); - int stackSerialNumber = in.readInt(); - StackTrace stack = mState.getStackTrace(stackSerialNumber); - long superClassId = readId(); - long classLoaderId = readId(); - long signersId = readId(); - long protectionDomainId = readId(); - long reserved1 = readId(); - long reserved2 = readId(); - int instanceSize = in.readInt(); - - bytesRead = (7 * mIdSize) + 4 + 4; - - // Skip over the constant pool - int numEntries = in.readUnsignedShort(); - bytesRead += 2; - - for (int i = 0; i < numEntries; i++) { - in.readUnsignedShort(); - bytesRead += 2 + skipValue(); - } - - // Static fields - numEntries = in.readUnsignedShort(); - bytesRead += 2; - - String[] staticFieldNames = new String[numEntries]; - int[] staticFieldTypes = new int[numEntries]; - ByteArrayOutputStream staticFieldValues = new ByteArrayOutputStream(); - byte[] buffer = mFieldBuffer; - - for (int i = 0; i < numEntries; i++) { - staticFieldNames[i] = mStrings.get(readId()); - - int fieldType = in.readByte(); - int fieldSize = Types.getTypeSize(fieldType); - staticFieldTypes[i] = fieldType; - - in.readFully(buffer, 0, fieldSize); - staticFieldValues.write(buffer, 0, fieldSize); - - bytesRead += mIdSize + 1 + fieldSize; - } - - // Instance fields - numEntries = in.readUnsignedShort(); - bytesRead += 2; - - String[] names = new String[numEntries]; - int[] types = new int[numEntries]; - - for (int i = 0; i < numEntries; i++) { - long fieldName = readId(); - int type = in.readUnsignedByte(); - - names[i] = mStrings.get(fieldName); - types[i] = type; - - bytesRead += mIdSize + 1; - } - - ClassObj theClass = new ClassObj(id, stack, mClassNames.get(id)); - - theClass.setStaticFieldNames(staticFieldNames); - theClass.setStaticFieldTypes(staticFieldTypes); - theClass.setStaticFieldValues(staticFieldValues.toByteArray()); - - theClass.setSuperclassId(superClassId); - theClass.setFieldNames(names); - theClass.setFieldTypes(types); - theClass.setSize(instanceSize); - - theClass.setHeap(mState.mCurrentHeap); - - mState.addClass(id, theClass); - - return bytesRead; - } - - private int loadInstanceDump() throws IOException { - long id = readId(); - int stackId = mInput.readInt(); - StackTrace stack = mState.getStackTrace(stackId); - long classId = readId(); - int remaining = mInput.readInt(); - ClassInstance instance = new ClassInstance(id, stack, classId); - - instance.loadFieldData(mInput, remaining); - instance.setHeap(mState.mCurrentHeap); - mState.addInstance(id, instance); - - return mIdSize + 4 + mIdSize + 4 + remaining; - } - - private int loadObjectArrayDump() throws IOException { - long id = readId(); - int stackId = mInput.readInt(); - StackTrace stack = mState.getStackTrace(stackId); - int numElements = mInput.readInt(); - long classId = readId(); - int totalBytes = numElements * mIdSize; - byte[] data = new byte[totalBytes]; - String className = mClassNames.get(classId); - - mInput.readFully(data); - - ArrayInstance array = new ArrayInstance(id, stack, Types.OBJECT, - numElements, data); - - array.mClassId = classId; - array.setHeap(mState.mCurrentHeap); - mState.addInstance(id, array); - - return mIdSize + 4 + 4 + mIdSize + totalBytes; - } - - private int loadPrimitiveArrayDump() throws IOException { - long id = readId(); - int stackId = mInput.readInt(); - StackTrace stack = mState.getStackTrace(stackId); - int numElements = mInput.readInt(); - int type = mInput.readUnsignedByte(); - int size = Types.getTypeSize(type); - int totalBytes = numElements * size; - byte[] data = new byte[totalBytes]; - - mInput.readFully(data); - - ArrayInstance array = new ArrayInstance(id, stack, type, numElements, - data); - - array.setHeap(mState.mCurrentHeap); - mState.addInstance(id, array); - - return mIdSize + 4 + 4 + 1 + totalBytes; - } - - private int loadJniMonitor() throws IOException { - long id = readId(); - int threadSerialNumber = mInput.readInt(); - int stackDepth = mInput.readInt(); - ThreadObj thread = mState.getThread(threadSerialNumber); - StackTrace trace = mState.getStackTraceAtDepth(thread.mStackTrace, - stackDepth); - RootObj root = new RootObj(RootType.NATIVE_MONITOR, id, - threadSerialNumber, trace); - - root.setHeap(mState.mCurrentHeap); - mState.addRoot(root); - - return mIdSize + 4 + 4; - } - - private int skipValue() throws IOException { - int type = mInput.readUnsignedByte(); - int size = Types.getTypeSize(type); - - skipFully(size); - - return size + 1; - } - - /* - * BufferedInputStream will not skip(int) the entire requested number - * of bytes if it extends past the current buffer boundary. So, this - * routine is needed to actually skip over the requested number of bytes - * using as many iterations as needed. - */ - private void skipFully(long numBytes) throws IOException { - while (numBytes > 0) { - long skipped = mInput.skip(numBytes); - - numBytes -= skipped; - } - } -} diff --git a/hit/src/com/android/hit/Instance.java b/hit/src/com/android/hit/Instance.java deleted file mode 100644 index 6afa2b26a..000000000 --- a/hit/src/com/android/hit/Instance.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -public abstract class Instance { - long mId; - - // Id of the ClassObj of which this object is an instance - long mClassId; - - // The stack in which this object was allocated - StackTrace mStack; - - // The heap in which this object was allocated (app, zygote, etc) - Heap mHeap; - - // The size of this object - int mSize; - - public interface Filter { - public boolean accept(Instance instance); - } - - // List of all objects that hold a live reference to this object - private ArrayList<Instance> mParents; - - /* - * After the whole HPROF file is read and parsed this method will be - * called on all heap objects so that they can resolve their internal - * object references. - * - * The super-State is passed in because some object references (such - * as interned Strings and static class fields) may need to be searched - * for in a heap other than the one this Instance is in. - */ - public abstract void resolveReferences(State state); - - /* - * Some operations require gathering all the objects in a given section - * of the object graph. If non-null, the filter is applied to each - * node in the graph to determine if it should be added to the result - * set. - */ - public abstract void visit(Set<Instance> resultSet, Filter filter); - - public void setSize(int size) { - mSize = size; - } - - public final int getCompositeSize() { - HashSet<Instance> set = new HashSet<Instance>(); - - visit(set, null); - - int size = 0; - - for (Instance instance: set) { - size += instance.getSize(); - } - - return size; - } - - // Returns the instrinsic size of a given object - public int getSize() { - return mSize; - } - - public abstract String getTypeName(); - - public void setHeap(Heap heap) { - mHeap = heap; - } - - // Add to the list of objects that have a hard reference to this Instance - public void addParent(Instance parent) { - if (mParents == null) { - mParents = new ArrayList<Instance>(); - } - - mParents.add(parent); - } - - public ArrayList<Instance> getParents() { - if (mParents == null) { - mParents = new ArrayList<Instance>(); - } - - return mParents; - } - - /* - * If this object has a reference to the object identified by id, return - * a String describing the reference in detail. - */ - public String describeReferenceTo(long id) { - return "No reference to 0x" + Long.toHexString(id); - } -} diff --git a/hit/src/com/android/hit/Main.java b/hit/src/com/android/hit/Main.java deleted file mode 100644 index 4ed5c11c9..000000000 --- a/hit/src/com/android/hit/Main.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.io.BufferedInputStream; -import java.io.DataInputStream; -import java.io.FileInputStream; -import java.util.Map; -import java.util.Set; - -public class Main -{ - public static void main(String argv[]) { - FileInputStream fis; - BufferedInputStream bis; - DataInputStream dis; - - try { - fis = new FileInputStream(argv[0]); - bis = new BufferedInputStream(fis); - dis = new DataInputStream(bis); - - State state = (new HprofParser(dis)).parse(); - - dis.close(); - - testClassesQuery(state); - testAllClassesQuery(state); - testFindInstancesOf(state); - testFindAllInstancesOf(state); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static void testClassesQuery(State state) { - String[] x = new String[] { - "char[", - "javax.", - "org.xml.sax" - }; - - Map<String, Set<ClassObj>> someClasses = Queries.classes(state, x); - - for (String thePackage: someClasses.keySet()) { - System.out.println("------------------- " + thePackage); - - Set<ClassObj> classes = someClasses.get(thePackage); - - for (ClassObj theClass: classes) { - System.out.println(" " + theClass.mClassName); - } - } - } - - private static void testAllClassesQuery(State state) { - Map<String, Set<ClassObj>> allClasses = Queries.allClasses(state); - - for (String thePackage: allClasses.keySet()) { - System.out.println("------------------- " + thePackage); - - Set<ClassObj> classes = allClasses.get(thePackage); - - for (ClassObj theClass: classes) { - System.out.println(" " + theClass.mClassName); - } - } - } - - private static void testFindInstancesOf(State state) { - Instance[] instances = Queries.instancesOf(state, "java.lang.String"); - - System.out.println("There are " + instances.length + " Strings."); - } - - private static void testFindAllInstancesOf(State state) { - Instance[] instances = Queries.allInstancesOf(state, - "android.graphics.drawable.Drawable"); - - System.out.println("There are " + instances.length - + " instances of Drawables and its subclasses."); - } -} diff --git a/hit/src/com/android/hit/Queries.java b/hit/src/com/android/hit/Queries.java deleted file mode 100644 index 0dac79647..000000000 --- a/hit/src/com/android/hit/Queries.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -public class Queries { - /* - * NOTES: Here's a list of the queries that can be done in hat and - * how you'd perform a similar query here in hit: - * - * hat hit - * ------------------------------------------------------------------------ - * allClasses classes - * allClassesWithPlatform allClasses - * class findClass - * instances instancesOf - * allInstances allInstancesOf - * object findObject - * showRoots getRoots - * newInstances newInstances - * - * reachableFrom make a call to findObject to get the target - * parent object, this will give you an Instance. - * Then call visit(Set, Filter) on that to have - * it build the set of objects in its subgraph. - * - * rootsTo make a call to findObject on the leaf node - * in question, this will give you an Instance. - * Instances have an ArrayList of all of the - * parent objects that refer to it. You can - * follow those parent links until you hit an - * object whose parent is null or a ThreadObj. - * You've not successfully traced the paths to - * the roots. - */ - - private static final String DEFAULT_PACKAGE = "<default>"; - - /* - * Produce a collection of all classes, broken down by package. - * The keys of the resultant map iterate in sorted package order. - * The values of the map are the classes defined in each package. - */ - public static Map<String, Set<ClassObj>> allClasses(State state) { - return classes(state, null); - } - - public static Map<String, Set<ClassObj>> classes(State state, - String[] excludedPrefixes) { - TreeMap<String, Set<ClassObj>> result = - new TreeMap<String, Set<ClassObj>>(); - - Set<ClassObj> classes = new TreeSet<ClassObj>(); - - // Build a set of all classes across all heaps - for (Heap heap: state.mHeaps.values()) { - classes.addAll(heap.mClassesById.values()); - } - - // Filter it if needed - if (excludedPrefixes != null) { - final int N = excludedPrefixes.length; - Iterator<ClassObj> iter = classes.iterator(); - - while (iter.hasNext()) { - ClassObj theClass = iter.next(); - String classPath = theClass.toString(); - - for (int i = 0; i < N; i++) { - if (classPath.startsWith(excludedPrefixes[i])) { - iter.remove(); - break; - } - } - } - } - - // Now that we have a final list of classes, group them by package - for (ClassObj theClass: classes) { - String packageName = DEFAULT_PACKAGE; - int lastDot = theClass.mClassName.lastIndexOf('.'); - - if (lastDot != -1) { - packageName = theClass.mClassName.substring(0, lastDot); - } - - Set<ClassObj> classSet = result.get(packageName); - - if (classSet == null) { - classSet = new TreeSet<ClassObj>(); - result.put(packageName, classSet); - } - - classSet.add(theClass); - } - - return result; - } - - /* - * It's sorta sad that this is a pass-through call, but it seems like - * having all of the hat-like query methods in one place is a good thing - * even if there is duplication of effort. - */ - public static ClassObj findClass(State state, String name) { - return state.findClass(name); - } - - /* - * Return an array of instances of the given class. This does not include - * instances of subclasses. - */ - public static Instance[] instancesOf(State state, String baseClassName) { - ClassObj theClass = state.findClass(baseClassName); - - if (theClass == null) { - throw new IllegalArgumentException("Class not found: " - + baseClassName); - } - - Instance[] instances = new Instance[theClass.mInstances.size()]; - - return theClass.mInstances.toArray(instances); - } - - /* - * Return an array of instances of the given class. This includes - * instances of subclasses. - */ - public static Instance[] allInstancesOf(State state, String baseClassName) { - ClassObj theClass = state.findClass(baseClassName); - - if (theClass == null) { - throw new IllegalArgumentException("Class not found: " - + baseClassName); - } - - ArrayList<ClassObj> classList = new ArrayList<ClassObj>(); - - classList.add(theClass); - classList.addAll(traverseSubclasses(theClass)); - - ArrayList<Instance> instanceList = new ArrayList<Instance>(); - - for (ClassObj someClass: classList) { - instanceList.addAll(someClass.mInstances); - } - - Instance[] result = new Instance[instanceList.size()]; - - instanceList.toArray(result); - - return result; - } - - private static ArrayList<ClassObj> traverseSubclasses(ClassObj base) { - ArrayList<ClassObj> result = new ArrayList<ClassObj>(); - - for (ClassObj subclass: base.mSubclasses) { - result.add(subclass); - result.addAll(traverseSubclasses(subclass)); - } - - return result; - } - - /* - * Find a reference to an object based on its id. The id should be - * in hexadecimal. - */ - public static Instance findObject(State state, String id) { - long id2 = Long.parseLong(id, 16); - - return state.findReference(id2); - } - - public static Collection<RootObj> getRoots(State state) { - HashSet<RootObj> result = new HashSet<RootObj>(); - - for (Heap heap: state.mHeaps.values()) { - result.addAll(heap.mRoots); - } - - return result; - } - - public static final Instance[] newInstances(State older, State newer) { - ArrayList<Instance> resultList = new ArrayList<Instance>(); - - for (Heap newHeap: newer.mHeaps.values()) { - Heap oldHeap = older.getHeap(newHeap.mName); - - if (oldHeap == null) { - continue; - } - - for (Instance instance: newHeap.mInstances.values()) { - Instance oldInstance = oldHeap.getInstance(instance.mId); - - /* - * If this instance wasn't in the old heap, or was there, - * but that ID was for an obj of a different type, then we have - * a newly allocated object and we should report it in the - * results. - */ - if ((oldInstance == null) - || (instance.mClassId != oldInstance.mClassId)) { - resultList.add(instance); - } - } - } - - Instance[] resultArray = new Instance[resultList.size()]; - - return resultList.toArray(resultArray); - } -} diff --git a/hit/src/com/android/hit/RootObj.java b/hit/src/com/android/hit/RootObj.java deleted file mode 100644 index a9acd3544..000000000 --- a/hit/src/com/android/hit/RootObj.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.util.Set; - -public class RootObj extends Instance { - RootType mType = RootType.UNKNOWN; - int mIndex; - int mThread; - - /* - * These two fields are only used by roots that are static - * fields of class objects - */ - long mParent; - String mComment; - - public RootObj(RootType type) { - this(type, 0, 0, null); - } - - public RootObj(RootType type, long id) { - this(type, id, 0, null); - } - - public RootObj(RootType type, long id, int thread, StackTrace stack) { - mType = type; - mId = id; - mThread = thread; - mStack = stack; - } - - public final String getClassName(State state) { - ClassObj theClass; - - if (mType == RootType.SYSTEM_CLASS) { - theClass = state.findClass(mId); - } else { - Instance instance = state.findReference(mId); - - theClass = state.findClass(instance.mClassId); - } - - if (theClass == null) { - return "no class defined!!"; - } - - return theClass.mClassName; - } - - @Override - public final int getSize() { - Instance instance = null; - - if (mType == RootType.SYSTEM_CLASS) { - instance = mHeap.mState.findClass(mId); - } else { - instance = mHeap.mState.findReference(mId); - } - - if (instance == null) { - return 0; - } - - return instance.getSize(); - } - - @Override - public final void visit(Set<Instance> resultSet, Filter filter) { - if (resultSet.contains(this)) { - return; - } - - if (filter != null) { - if (filter.accept(this)) { - resultSet.add(this); - } - } else { - resultSet.add(this); - } - } - - @Override - public final void resolveReferences(State state) { - // Nothing to do here - } - - @Override - public final String getTypeName() { - return "root " + mType.getName(); - } - - public final String toString() { - return String.format("%s@0x08x", mType.getName(), mId); - } -} diff --git a/hit/src/com/android/hit/RootType.java b/hit/src/com/android/hit/RootType.java deleted file mode 100644 index 209ed1be0..000000000 --- a/hit/src/com/android/hit/RootType.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -public enum RootType { - UNREACHABLE (0, "unreachable object"), - INVALID_TYPE (1, "invalid type"), - INTERNED_STRING (2, "interned string"), - UNKNOWN (3, "unknown"), - SYSTEM_CLASS (4, "system class"), - VM_INTERNAL (5, "vm internal"), - DEBUGGER (6, "debugger"), - NATIVE_LOCAL (7, "native local"), - NATIVE_STATIC (8, "native static"), - THREAD_BLOCK (9, "thread block"), - BUSY_MONITOR (10, "busy monitor"), - NATIVE_MONITOR (11, "native monitor"), - REFERENCE_CLEANUP (12, "reference cleanup"), - FINALIZING (13, "finalizing"), - JAVA_LOCAL (14, "java local"), - NATIVE_STACK (15, "native stack"), - JAVA_STATIC (16, "java static"); - - private final int mType; - private final String mName; - - RootType(int type, String name) { - mType = type; - mName = name; - } - - public final int getType() { - return mType; - } - - public final String getName() { - return mName; - } -} diff --git a/hit/src/com/android/hit/StackFrame.java b/hit/src/com/android/hit/StackFrame.java deleted file mode 100644 index 2ae7f326e..000000000 --- a/hit/src/com/android/hit/StackFrame.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -public class StackFrame { - public static final int NO_LINE_NUMBER = 0; - public static final int UNKNOWN_LOCATION = -1; - public static final int COMPILED_METHOD = -2; - public static final int NATIVE_METHOD = -3; - - long mId; - String mMethodName; - String mSignature; - String mFilename; - int mSerialNumber; - int mLineNumber; - - public StackFrame(long id, String method, String sig, String file, - int serial, int line) { - mId = id; - mMethodName = method; - mSignature = sig; - mFilename = file; - mSerialNumber = serial; - mLineNumber = line; - } - - private final String lineNumberString() { - switch (mLineNumber) { - case NO_LINE_NUMBER: return "No line number"; - case UNKNOWN_LOCATION: return "Unknown line number"; - case COMPILED_METHOD: return "Compiled method"; - case NATIVE_METHOD: return "Native method"; - - default: return String.valueOf(mLineNumber); - } - } - - public final String toString() { - return mMethodName - + mSignature.replace('/', '.') - + " - " - + mFilename + ":" - + lineNumberString(); - } -} diff --git a/hit/src/com/android/hit/StackTrace.java b/hit/src/com/android/hit/StackTrace.java deleted file mode 100644 index 53cb86dbe..000000000 --- a/hit/src/com/android/hit/StackTrace.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -public class StackTrace { - int mSerialNumber; - int mThreadSerialNumber; - StackFrame[] mFrames; - - /* - * For subsets of the stack frame we'll reference the parent list of frames - * but keep track of its offset into the parent's list of stack frame ids. - * This alleviates the need to constantly be duplicating subsections of the - * list of stack frame ids. - */ - StackTrace mParent = null; - int mOffset = 0; - - private StackTrace() { - - } - - public StackTrace(int serial, int thread, StackFrame[] frames) { - mSerialNumber = serial; - mThreadSerialNumber = thread; - mFrames = frames; - } - - public final StackTrace fromDepth(int startingDepth) { - StackTrace result = new StackTrace(); - - if (mParent != null) { - result.mParent = mParent; - } else { - result.mParent = this; - } - - result.mOffset = startingDepth + mOffset; - - return result; - } - - public final void dump() { - final int N = mFrames.length; - - for (int i = 0; i < N; i++) { - System.out.println(mFrames[i].toString()); - } - } -} diff --git a/hit/src/com/android/hit/State.java b/hit/src/com/android/hit/State.java deleted file mode 100644 index 96c944d91..000000000 --- a/hit/src/com/android/hit/State.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -import java.util.ArrayList; -import java.util.HashMap; - -/* - * State is a snapshot of all of the heaps, and related meta-data, for - * the runtime at a given instant. - * - * During parsing of the HPROF file HEAP_DUMP_INFO chunks change which heap - * is being referenced. - */ -public class State { - HashMap<Integer, Heap> mHeaps; - Heap mCurrentHeap; - - public State() { - mHeaps = new HashMap<Integer, Heap>(); - setToDefaultHeap(); - } - - public Heap setToDefaultHeap() { - return setHeapTo(0, "default"); - } - - public Heap setHeapTo(int id, String name) { - Heap heap = mHeaps.get(id); - - if (heap == null) { - heap = new Heap(name); - heap.mState = this; - mHeaps.put(id, heap); - } - - mCurrentHeap = heap; - - return mCurrentHeap; - } - - public Heap getHeap(int id) { - return mHeaps.get(id); - } - - public Heap getHeap(String name) { - for (Heap heap: mHeaps.values()) { - if (heap.mName.equals(name)) { - return heap; - } - } - - return null; - } - - public final void addStackFrame(StackFrame theFrame) { - mCurrentHeap.addStackFrame(theFrame); - } - - public final StackFrame getStackFrame(long id) { - return mCurrentHeap.getStackFrame(id); - } - - public final void addStackTrace(StackTrace theTrace) { - mCurrentHeap.addStackTrace(theTrace); - } - - public final StackTrace getStackTrace(int traceSerialNumber) { - return mCurrentHeap.getStackTrace(traceSerialNumber); - } - - public final StackTrace getStackTraceAtDepth(int traceSerialNumber, - int depth) { - return mCurrentHeap.getStackTraceAtDepth(traceSerialNumber, depth); - } - - public final void addRoot(RootObj root) { - mCurrentHeap.addRoot(root); - } - - public final void addThread(ThreadObj thread, int serialNumber) { - mCurrentHeap.addThread(thread, serialNumber); - } - - public final ThreadObj getThread(int serialNumber) { - return mCurrentHeap.getThread(serialNumber); - } - - public final void addInstance(long id, Instance instance) { - mCurrentHeap.addInstance(id, instance); - } - - public final void addClass(long id, ClassObj theClass) { - mCurrentHeap.addClass(id, theClass); - } - - public final Instance findReference(long id) { - for (Heap heap: mHeaps.values()) { - Instance instance = heap.getInstance(id); - - if (instance != null) { - return instance; - } - } - - // Couldn't find an instance of a class, look for a class object - return findClass(id); - } - - public final ClassObj findClass(long id) { - for (Heap heap: mHeaps.values()) { - ClassObj theClass = heap.getClass(id); - - if (theClass != null) { - return theClass; - } - } - - return null; - } - - public final ClassObj findClass(String name) { - for (Heap heap: mHeaps.values()) { - ClassObj theClass = heap.getClass(name); - - if (theClass != null) { - return theClass; - } - } - - return null; - } - - public final void dumpInstanceCounts() { - for (Heap heap: mHeaps.values()) { - System.out.println( - "+------------------ instance counts for heap: " + heap.mName); - heap.dumpInstanceCounts(); - } - } - - public final void dumpSizes() { - for (Heap heap: mHeaps.values()) { - System.out.println( - "+------------------ sizes for heap: " + heap.mName); - heap.dumpSizes(); - } - } - - public final void dumpSubclasses() { - for (Heap heap: mHeaps.values()) { - System.out.println( - "+------------------ subclasses for heap: " + heap.mName); - heap.dumpSubclasses(); - } - } - - public final void resolveReferences() { - for (Heap heap: mHeaps.values()) { - heap.resolveInstanceRefs(this); - heap.resolveClassStatics(this); - heap.resolveRoots(this); - } - } -} diff --git a/hit/src/com/android/hit/ThreadObj.java b/hit/src/com/android/hit/ThreadObj.java deleted file mode 100644 index 32a73f024..000000000 --- a/hit/src/com/android/hit/ThreadObj.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -public class ThreadObj { - long mId; - int mStackTrace; - - public ThreadObj(long id, int stackTrace) { - mId = id; - mStackTrace = stackTrace; - } -} diff --git a/hit/src/com/android/hit/Types.java b/hit/src/com/android/hit/Types.java deleted file mode 100644 index 62228cea6..000000000 --- a/hit/src/com/android/hit/Types.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2008 Google Inc. - * - * 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. - */ - -package com.android.hit; - -public class Types { - private static int mIdSize = 4; - - public static final int OBJECT = 2; - public static final int BOOLEAN = 4; - public static final int CHAR = 5; - public static final int FLOAT = 6; - public static final int DOUBLE = 7; - public static final int BYTE = 8; - public static final int SHORT = 9; - public static final int INT = 10; - public static final int LONG = 11; - - public static final void setIdSize(int size) { - mIdSize = size; - } - - public static final int getTypeSize(int type) { - switch (type) { - case '[': return mIdSize; // array object - case 'L': return mIdSize; // object - case 'Z': return 1; // boolean - case 'C': return 2; // char - case 'F': return 4; // float - case 'D': return 8; // double - case 'B': return 1; // byte - case 'S': return 2; // short - case 'I': return 4; // int - case 'J': return 8; // long - - case OBJECT: return mIdSize; - case BOOLEAN: return 1; - case CHAR: return 2; - case FLOAT: return 4; - case DOUBLE: return 8; - case BYTE: return 1; - case SHORT: return 2; - case INT: return 4; - case LONG: return 8; - } - - throw new IllegalArgumentException("Illegal type signature: " + type); - } - - public static final String getTypeName(int type) { - switch (type) { - case '[': return "array"; - case 'L': return "object"; - case 'Z': return "boolean"; - case 'C': return "char"; - case 'F': return "float"; - case 'D': return "double"; - case 'B': return "byte"; - case 'S': return "short"; - case 'I': return "int"; - case 'J': return "long"; - - case OBJECT: return "object"; - case BOOLEAN: return "boolean"; - case CHAR: return "char"; - case FLOAT: return "float"; - case DOUBLE: return "double"; - case BYTE: return "byte"; - case SHORT: return "short"; - case INT: return "int"; - case LONG: return "long"; - } - - throw new IllegalArgumentException("Illegal type signature: " + type); - } -} diff --git a/hit/test/testparser b/hit/test/testparser deleted file mode 100755 index a3a722ed0..000000000 --- a/hit/test/testparser +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -find ../src -name \*java | xargs javac -d build -Xlint:unchecked - -# debug launch line tha turns off the jit and runs a debug server -#java -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,address=53635,server=y,suspend=y -cp build com.android.hit.Main ../samples/android.hprof - -java -cp build com.android.hit.Main ../samples/android.hprof diff --git a/libdex/Android.mk b/libdex/Android.mk index d07af63ec..15e7ba703 100644 --- a/libdex/Android.mk +++ b/libdex/Android.mk @@ -49,12 +49,14 @@ include $(CLEAR_VARS) #LOCAL_CFLAGS += -UNDEBUG -DDEBUG=1 LOCAL_SRC_FILES := $(dex_src_files) LOCAL_C_INCLUDES += $(dex_include_files) +LOCAL_CPPFLAGS := -std=gnu++11 LOCAL_STATIC_LIBRARIES := liblog LOCAL_WHOLE_STATIC_LIBRARIES := libziparchive LOCAL_SHARED_LIBRARIES := libutils LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libdex LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_STATIC_LIBRARY) endif # !SDK_ONLY @@ -68,8 +70,11 @@ endif # !SDK_ONLY include $(CLEAR_VARS) LOCAL_SRC_FILES := $(dex_src_files) LOCAL_C_INCLUDES += $(dex_include_files) +LOCAL_CPPFLAGS := -std=gnu++11 LOCAL_STATIC_LIBRARIES := liblog libutils LOCAL_WHOLE_STATIC_LIBRARIES := libziparchive-host LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libdex +LOCAL_32_BIT_ONLY := true +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_HOST_STATIC_LIBRARY) diff --git a/libdex/DexFile.h b/libdex/DexFile.h index 710400525..e8ab31924 100644 --- a/libdex/DexFile.h +++ b/libdex/DexFile.h @@ -33,7 +33,44 @@ #ifndef LIBDEX_DEXFILE_H_ #define LIBDEX_DEXFILE_H_ -#include "vm/Common.h" // basic type defs, e.g. u1/u2/u4/u8, and LOG +#ifndef LOG_TAG +# define LOG_TAG "libdex" +#endif + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <assert.h> +#include "cutils/log.h" + +/* + * If "very verbose" logging is enabled, make it equivalent to ALOGV. + * Otherwise, make it disappear. + * + * Define this above the #include "Dalvik.h" to enable for only a + * single file. + */ +/* #define VERY_VERBOSE_LOG */ +#if defined(VERY_VERBOSE_LOG) +# define LOGVV ALOGV +# define IF_LOGVV() IF_ALOGV() +#else +# define LOGVV(...) ((void)0) +# define IF_LOGVV() if (false) +#endif + +/* + * These match the definitions in the VM specification. + */ +typedef uint8_t u1; +typedef uint16_t u2; +typedef uint32_t u4; +typedef uint64_t u8; +typedef int8_t s1; +typedef int16_t s2; +typedef int32_t s4; +typedef int64_t s8; + #include "libdex/SysUtil.h" /* diff --git a/libdex/DexSwapVerify.cpp b/libdex/DexSwapVerify.cpp index ff47ab5d1..7f18831d6 100644 --- a/libdex/DexSwapVerify.cpp +++ b/libdex/DexSwapVerify.cpp @@ -31,35 +31,9 @@ #include <stdlib.h> #include <string.h> -#ifndef __BYTE_ORDER -# error "byte ordering not defined" -#endif - -#if __BYTE_ORDER == __LITTLE_ENDIAN -# define SWAP2(_value) (_value) -# define SWAP4(_value) (_value) -# define SWAP8(_value) (_value) -#else -# define SWAP2(_value) endianSwapU2((_value)) -# define SWAP4(_value) endianSwapU4((_value)) -# define SWAP8(_value) endianSwapU8((_value)) -static u2 endianSwapU2(u2 value) { - return (value >> 8) | (value << 8); -} -static u4 endianSwapU4(u4 value) { - /* ABCD --> CDAB --> DCBA */ - value = (value >> 16) | (value << 16); - return ((value & 0xff00ff00) >> 8) | ((value << 8) & 0xff00ff00); -} -static u8 endianSwapU8(u8 value) { - /* ABCDEFGH --> EFGHABCD --> GHEFCDAB --> HGFEDCBA */ - value = (value >> 32) | (value << 32); - value = ((value & 0xffff0000ffff0000ULL) >> 16) | - ((value << 16) & 0xffff0000ffff0000ULL); - return ((value & 0xff00ff00ff00ff00ULL) >> 8) | - ((value << 8) & 0xff00ff00ff00ff00ULL); -} -#endif +#define SWAP2(_value) (_value) +#define SWAP4(_value) (_value) +#define SWAP8(_value) (_value) #define SWAP_FIELD2(_field) (_field) = SWAP2(_field) #define SWAP_FIELD4(_field) (_field) = SWAP4(_field) diff --git a/libdex/OptInvocation.cpp b/libdex/OptInvocation.cpp index 031ec9177..be7f70b50 100644 --- a/libdex/OptInvocation.cpp +++ b/libdex/OptInvocation.cpp @@ -18,8 +18,6 @@ * Utility functions for dealing with optimized dex files. */ -#include "vm/DalvikVersion.h" - #include <stdint.h> #include <stdlib.h> #include <unistd.h> diff --git a/libdex/SysUtil.cpp b/libdex/SysUtil.cpp index 825315ecc..5650be539 100644 --- a/libdex/SysUtil.cpp +++ b/libdex/SysUtil.cpp @@ -24,7 +24,7 @@ #include <stdio.h> #include <unistd.h> #include <string.h> -#ifdef HAVE_POSIX_FILEMAP +#if !defined(__MINGW32__) # include <sys/mman.h> #endif #include <limits.h> @@ -40,7 +40,7 @@ */ static void* sysCreateAnonShmem(size_t length) { -#ifdef HAVE_POSIX_FILEMAP +#if !defined(__MINGW32__) void* ptr; ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, @@ -106,7 +106,7 @@ static int getFileStartAndLength(int fd, off_t *start_, size_t *length_) return 0; } -#ifndef HAVE_POSIX_FILEMAP +#if defined(__MINGW32__) int sysFakeMapFile(int fd, MemMapping* pMap) { /* No MMAP, just fake it by copying the bits. @@ -149,7 +149,7 @@ int sysFakeMapFile(int fd, MemMapping* pMap) */ int sysMapFileInShmemWritableReadOnly(int fd, MemMapping* pMap) { -#ifdef HAVE_POSIX_FILEMAP +#if !defined(__MINGW32__) off_t start; size_t length; void* memPtr; @@ -193,7 +193,7 @@ int sysMapFileInShmemWritableReadOnly(int fd, MemMapping* pMap) int sysMapFileSegmentInShmem(int fd, off_t start, size_t length, MemMapping* pMap) { -#ifdef HAVE_POSIX_FILEMAP +#if !defined(__MINGW32__) size_t actualLength; off_t actualStart; int adjust; @@ -239,7 +239,7 @@ int sysMapFileSegmentInShmem(int fd, off_t start, size_t length, int sysChangeMapAccess(void* addr, size_t length, int wantReadWrite, MemMapping* pMap) { -#ifdef HAVE_POSIX_FILEMAP +#if !defined(__MINGW32__) /* * Verify that "addr" is part of this mapping file. */ @@ -278,7 +278,7 @@ int sysChangeMapAccess(void* addr, size_t length, int wantReadWrite, */ void sysReleaseShmem(MemMapping* pMap) { -#ifdef HAVE_POSIX_FILEMAP +#if !defined(__MINGW32__) if (pMap->baseAddr == NULL && pMap->baseLength == 0) return; diff --git a/libdex/ZipArchive.h b/libdex/ZipArchive.h index c4794ce0d..e293bf0f9 100644 --- a/libdex/ZipArchive.h +++ b/libdex/ZipArchive.h @@ -70,7 +70,7 @@ DEX_INLINE int dexZipGetArchiveFd(const ZipArchiveHandle pArchive) { */ DEX_INLINE int dexZipFindEntry(const ZipArchiveHandle pArchive, const char* entryName, ZipEntry* data) { - return FindEntry(pArchive, entryName, data); + return FindEntry(pArchive, ZipEntryName(entryName), data); } /* diff --git a/libdex/sha1.cpp b/libdex/sha1.cpp index 15a81cca3..60c4d9395 100644 --- a/libdex/sha1.cpp +++ b/libdex/sha1.cpp @@ -93,12 +93,9 @@ A million repetitions of "a" # include <unistd.h> # include <stdlib.h> //# include <endian.h> - -#include "DexFile.h" // want common byte ordering def - -# if __BYTE_ORDER == __LITTLE_ENDIAN +//# if __BYTE_ORDER == __LITTLE_ENDIAN # define X_LITTLE_ENDIAN -# endif +//# endif #endif #include <ctype.h> diff --git a/tools/dmtracedump/Android.mk b/tools/dmtracedump/Android.mk index 5d3146e9a..933f4e5d8 100644 --- a/tools/dmtracedump/Android.mk +++ b/tools/dmtracedump/Android.mk @@ -10,7 +10,6 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := TraceDump.c LOCAL_CFLAGS += -O0 -g -LOCAL_C_INCLUDES += dalvik/vm LOCAL_MODULE_TAGS := optional LOCAL_MODULE := dmtracedump include $(BUILD_HOST_EXECUTABLE) @@ -18,7 +17,6 @@ include $(BUILD_HOST_EXECUTABLE) include $(CLEAR_VARS) LOCAL_SRC_FILES := CreateTestTrace.c LOCAL_CFLAGS += -O0 -g -LOCAL_C_INCLUDES += dalvik/vm LOCAL_MODULE_TAGS := optional LOCAL_MODULE := create_test_dmtrace include $(BUILD_HOST_EXECUTABLE) diff --git a/tools/dmtracedump/Profile.h b/tools/dmtracedump/Profile.h new file mode 100644 index 000000000..efbedb35e --- /dev/null +++ b/tools/dmtracedump/Profile.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +/* + * Android's method call profiling goodies. + */ +#ifndef DALVIK_PROFILE_H_ +#define DALVIK_PROFILE_H_ + +/* + * Enumeration for the two "action" bits. + */ +enum { + METHOD_TRACE_ENTER = 0x00, // method entry + METHOD_TRACE_EXIT = 0x01, // method exit + METHOD_TRACE_UNROLL = 0x02, // method exited by exception unrolling + // 0x03 currently unused +}; + +#define TOKEN_CHAR '*' + +/* + * Common definitions, shared with the dump tool. + */ +#define METHOD_ACTION_MASK 0x03 /* two bits */ +#define METHOD_ID(_method) ((_method) & (~METHOD_ACTION_MASK)) +#define METHOD_ACTION(_method) (((unsigned int)(_method)) & METHOD_ACTION_MASK) +#define METHOD_COMBINE(_method, _action) ((_method) | (_action)) + +#endif // DALVIK_PROFILE_H_ diff --git a/tools/hprof-conv/HprofConv.c b/tools/hprof-conv/HprofConv.c index bd61e36f2..d37c12cb4 100644 --- a/tools/hprof-conv/HprofConv.c +++ b/tools/hprof-conv/HprofConv.c @@ -239,7 +239,7 @@ static int ebReadData(ExpandBuf* pBuf, FILE* in, size_t count, int eofExpected) if (eofExpected && feof(in) && !ferror(in)) { /* return without reporting an error */ } else { - fprintf(stderr, "ERROR: read %d of %d bytes\n", actual, count); + fprintf(stderr, "ERROR: read %zu of %zu bytes\n", actual, count); return -1; } } @@ -262,7 +262,7 @@ static int ebWriteData(ExpandBuf* pBuf, FILE* out) actual = fwrite(pBuf->storage, 1, pBuf->curLen, out); if (actual != pBuf->curLen) { - fprintf(stderr, "ERROR: write %d of %d bytes\n", actual, pBuf->curLen); + fprintf(stderr, "ERROR: write %zu of %zu bytes\n", actual, pBuf->curLen); return -1; } @@ -559,8 +559,8 @@ static int processHeapDump(ExpandBuf* pBuf, FILE* out, int flags) /* shouldn't get here */ default: - fprintf(stderr, "ERROR: unexpected subtype 0x%02x at offset %d\n", - subType, buf - origBuf); + fprintf(stderr, "ERROR: unexpected subtype 0x%02x at offset %zu\n", + subType, (size_t) (buf - origBuf)); goto bail; } diff --git a/vm/Common.h b/vm/Common.h deleted file mode 100644 index af31b97f8..000000000 --- a/vm/Common.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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. - */ - -/* - * Common defines for all Dalvik code. - */ -#ifndef DALVIK_COMMON_H_ -#define DALVIK_COMMON_H_ - -#ifndef LOG_TAG -# define LOG_TAG "dalvikvm" -#endif - -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <assert.h> -#include "cutils/log.h" - -#if defined(HAVE_ENDIAN_H) -# include <endian.h> -#else /*not HAVE_ENDIAN_H*/ -# define __BIG_ENDIAN 4321 -# define __LITTLE_ENDIAN 1234 -# if defined(HAVE_LITTLE_ENDIAN) -# define __BYTE_ORDER __LITTLE_ENDIAN -# else -# define __BYTE_ORDER __BIG_ENDIAN -# endif -#endif /*not HAVE_ENDIAN_H*/ - -#if !defined(NDEBUG) && defined(WITH_DALVIK_ASSERT) -# undef assert -# define assert(x) \ - ((x) ? ((void)0) : (ALOGE("ASSERT FAILED (%s:%d): %s", \ - __FILE__, __LINE__, #x), *(int*)39=39, (void)0) ) -#endif - -#define MIN(x,y) (((x) < (y)) ? (x) : (y)) -#define MAX(x,y) (((x) > (y)) ? (x) : (y)) - -#define LIKELY(exp) (__builtin_expect((exp) != 0, true)) -#define UNLIKELY(exp) (__builtin_expect((exp) != 0, false)) - -#define ALIGN_UP(x, n) (((size_t)(x) + (n) - 1) & ~((n) - 1)) -#define ALIGN_DOWN(x, n) ((size_t)(x) & -(n)) -#define ALIGN_UP_TO_PAGE_SIZE(p) ALIGN_UP(p, SYSTEM_PAGE_SIZE) -#define ALIGN_DOWN_TO_PAGE_SIZE(p) ALIGN_DOWN(p, SYSTEM_PAGE_SIZE) - -#define CLZ(x) __builtin_clz(x) - -/* - * If "very verbose" logging is enabled, make it equivalent to ALOGV. - * Otherwise, make it disappear. - * - * Define this above the #include "Dalvik.h" to enable for only a - * single file. - */ -/* #define VERY_VERBOSE_LOG */ -#if defined(VERY_VERBOSE_LOG) -# define LOGVV ALOGV -# define IF_LOGVV() IF_ALOGV() -#else -# define LOGVV(...) ((void)0) -# define IF_LOGVV() if (false) -#endif - - -/* - * These match the definitions in the VM specification. - */ -typedef uint8_t u1; -typedef uint16_t u2; -typedef uint32_t u4; -typedef uint64_t u8; -typedef int8_t s1; -typedef int16_t s2; -typedef int32_t s4; -typedef int64_t s8; - -/* - * Storage for primitive types and object references. - * - * Some parts of the code (notably object field access) assume that values - * are "left aligned", i.e. given "JValue jv", "jv.i" and "*((s4*)&jv)" - * yield the same result. This seems to be guaranteed by gcc on big- and - * little-endian systems. - */ -struct Object; - -union JValue { -#if defined(HAVE_LITTLE_ENDIAN) - u1 z; - s1 b; - u2 c; - s2 s; - s4 i; - s8 j; - float f; - double d; - Object* l; -#endif -#if defined(HAVE_BIG_ENDIAN) - struct { - u1 _z[3]; - u1 z; - }; - struct { - s1 _b[3]; - s1 b; - }; - struct { - u2 _c; - u2 c; - }; - struct { - s2 _s; - s2 s; - }; - s4 i; - s8 j; - float f; - double d; - void* l; -#endif -}; - -#define OFFSETOF_MEMBER(t, f) \ - (reinterpret_cast<char*>( \ - &reinterpret_cast<t*>(16)->f) - \ - reinterpret_cast<char*>(16)) - -#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) - -#endif // DALVIK_COMMON_H_ diff --git a/vm/DalvikVersion.h b/vm/DalvikVersion.h deleted file mode 100644 index e71c8393c..000000000 --- a/vm/DalvikVersion.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - */ - -/* - * Dalvik VM version info. - */ -#ifndef DALVIK_VERSION_H_ -#define DALVIK_VERSION_H_ - -/* - * The version we show to tourists. - */ -#define DALVIK_MAJOR_VERSION 1 -#define DALVIK_MINOR_VERSION 6 -#define DALVIK_BUG_VERSION 0 - -/* - * VM build number. This must change whenever something that affects the - * way classes load changes, e.g. field ordering or vtable layout. Changing - * this guarantees that the optimized form of the DEX file is regenerated. - */ -#define DALVIK_VM_BUILD 27 - -#endif // DALVIK_VERSION_H_ diff --git a/vm/Profile.h b/vm/Profile.h deleted file mode 100644 index 9059181a9..000000000 --- a/vm/Profile.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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. - */ - -/* - * Android's method call profiling goodies. - */ -#ifndef DALVIK_PROFILE_H_ -#define DALVIK_PROFILE_H_ - -#ifndef NOT_VM /* for utilities that sneakily include this file */ - -#include <stdio.h> - -struct Thread; // extern - - -/* boot init */ -bool dvmProfilingStartup(void); -void dvmProfilingShutdown(void); - -/* - * Method trace state. This is currently global. In theory we could make - * most of this per-thread. - */ -struct MethodTraceState { - /* active state */ - pthread_mutex_t startStopLock; - pthread_cond_t threadExitCond; - FILE* traceFile; - bool directToDdms; - int bufferSize; - int flags; - - int traceEnabled; - u1* buf; - volatile int curOffset; - u8 startWhen; - int overflow; - - int traceVersion; - size_t recordSize; - - bool samplingEnabled; - pthread_t samplingThreadHandle; -}; - -/* - * Memory allocation profiler state. This is used both globally and - * per-thread. - * - * If you add a field here, zero it out in dvmStartAllocCounting(). - */ -struct AllocProfState { - bool enabled; // is allocation tracking enabled? - - int allocCount; // #of objects allocated - int allocSize; // cumulative size of objects - - int failedAllocCount; // #of times an allocation failed - int failedAllocSize; // cumulative size of failed allocations - - int freeCount; // #of objects freed - int freeSize; // cumulative size of freed objects - - int gcCount; // #of times an allocation triggered a GC - - int classInitCount; // #of initialized classes - u8 classInitTime; // cumulative time spent in class init (nsec) -}; - - -/* - * Start/stop method tracing. - */ -void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize, - int flags, bool directToDdms, bool samplingEnabled, int intervalUs); -void dvmMethodTraceStop(void); - -/* - * Returns current method tracing mode. - */ -enum TracingMode { - TRACING_INACTIVE, - METHOD_TRACING_ACTIVE, - SAMPLE_PROFILING_ACTIVE, -}; -TracingMode dvmGetMethodTracingMode(void); - -/* - * Start/stop emulator tracing. - */ -void dvmEmulatorTraceStart(void); -void dvmEmulatorTraceStop(void); - -/* - * Start/stop Dalvik instruction counting. - */ -void dvmStartInstructionCounting(); -void dvmStopInstructionCounting(); - -/* - * Bit flags for dvmMethodTraceStart "flags" argument. These must match - * the values in android.os.Debug. - */ -enum { - TRACE_ALLOC_COUNTS = 0x01, -}; - -/* - * Call these when a method enters or exits. - */ -#define TRACE_METHOD_ENTER(_self, _method) \ - do { \ - if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \ - u4 cpuClockDiff = 0; \ - u4 wallClockDiff = 0; \ - dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \ - dvmMethodTraceAdd(_self, _method, METHOD_TRACE_ENTER, \ - cpuClockDiff, wallClockDiff); \ - } \ - if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \ - dvmEmitEmulatorTrace(_method, METHOD_TRACE_ENTER); \ - } while(0); -#define TRACE_METHOD_EXIT(_self, _method) \ - do { \ - if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \ - u4 cpuClockDiff = 0; \ - u4 wallClockDiff = 0; \ - dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \ - dvmMethodTraceAdd(_self, _method, METHOD_TRACE_EXIT, \ - cpuClockDiff, wallClockDiff); \ - } \ - if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \ - dvmEmitEmulatorTrace(_method, METHOD_TRACE_EXIT); \ - } while(0); -#define TRACE_METHOD_UNROLL(_self, _method) \ - do { \ - if (_self->interpBreak.ctl.subMode & kSubModeMethodTrace) { \ - u4 cpuClockDiff = 0; \ - u4 wallClockDiff = 0; \ - dvmMethodTraceReadClocks(_self, &cpuClockDiff, &wallClockDiff); \ - dvmMethodTraceAdd(_self, _method, METHOD_TRACE_UNROLL, \ - cpuClockDiff, wallClockDiff); \ - } \ - if (_self->interpBreak.ctl.subMode & kSubModeEmulatorTrace) \ - dvmEmitEmulatorTrace(_method, METHOD_TRACE_UNROLL); \ - } while(0); - -void dvmMethodTraceReadClocks(Thread* self, u4* cpuClockDiff, - u4* wallClockDiff); -void dvmMethodTraceAdd(struct Thread* self, const Method* method, int action, - u4 cpuClockDiff, u4 wallClockDiff); -void dvmEmitEmulatorTrace(const Method* method, int action); - -void dvmMethodTraceGCBegin(void); -void dvmMethodTraceGCEnd(void); -void dvmMethodTraceClassPrepBegin(void); -void dvmMethodTraceClassPrepEnd(void); - -extern "C" void dvmFastMethodTraceEnter(const Method* method, struct Thread* self); -extern "C" void dvmFastMethodTraceExit(struct Thread* self); -extern "C" void dvmFastNativeMethodTraceExit(const Method* method, struct Thread* self); - -/* - * Start/stop alloc counting. - */ -void dvmStartAllocCounting(void); -void dvmStopAllocCounting(void); - -#endif - - -/* - * Enumeration for the two "action" bits. - */ -enum { - METHOD_TRACE_ENTER = 0x00, // method entry - METHOD_TRACE_EXIT = 0x01, // method exit - METHOD_TRACE_UNROLL = 0x02, // method exited by exception unrolling - // 0x03 currently unused -}; - -#define TOKEN_CHAR '*' - -/* - * Common definitions, shared with the dump tool. - */ -#define METHOD_ACTION_MASK 0x03 /* two bits */ -#define METHOD_ID(_method) ((_method) & (~METHOD_ACTION_MASK)) -#define METHOD_ACTION(_method) (((unsigned int)(_method)) & METHOD_ACTION_MASK) -#define METHOD_COMBINE(_method, _action) ((_method) | (_action)) - -#endif // DALVIK_PROFILE_H_ |