1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dalvik.system.VMDebug
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "native/InternalNativePriv.h"
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden#include <string.h>
244b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden#include <unistd.h>
250171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden#include <errno.h>
260171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
28fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden/*
294b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden * Extracts the fd from a FileDescriptor object.
304b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden *
314b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden * If an error is encountered, or the extracted descriptor is numerically
324b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden * invalid, this returns -1 with an exception raised.
334b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden */
344b851a75f7712086a9fc4427f68c99b83725f37dAndy McFaddenstatic int getFileDescriptor(Object* obj)
354b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden{
364b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    assert(obj != NULL);
374b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    assert(strcmp(obj->clazz->descriptor, "Ljava/io/FileDescriptor;") == 0);
384b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden
394b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    InstField* field = dvmFindInstanceField(obj->clazz, "descriptor", "I");
404b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    if (field == NULL) {
414b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        dvmThrowException("Ljava/lang/NoSuchFieldException;",
424b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden            "No FileDescriptor.descriptor field");
434b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        return -1;
444b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    }
454b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden
464b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    int fd = dvmGetFieldInt(obj, field->byteOffset);
474b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    if (fd < 0) {
484b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        dvmThrowExceptionFmt("Ljava/lang/RuntimeException;",
494b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden            "Invalid file descriptor");
504b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        return -1;
514b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    }
524b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden
534b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    return fd;
544b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden}
554b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden
564b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden/*
57fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden * Convert an array of char* into a String[].
58fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden *
59fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden * Returns NULL on failure, with an exception raised.
60fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden */
61fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFaddenstatic ArrayObject* convertStringArray(char** strings, size_t count)
62fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden{
63364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes    Thread* self = dvmThreadSelf();
64364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes
65fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    /*
66fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden     * Allocate an array to hold the String objects.
67fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden     */
68fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    ClassObject* stringArrayClass =
69fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        dvmFindArrayClass("[Ljava/lang/String;", NULL);
70fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    if (stringArrayClass == NULL) {
71fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        /* shouldn't happen */
72fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        LOGE("Unable to find [Ljava/lang/String;\n");
73fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        dvmAbort();
74fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    }
75fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
76fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    ArrayObject* stringArray =
77fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        dvmAllocArrayByClass(stringArrayClass, count, ALLOC_DEFAULT);
78fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    if (stringArray == NULL) {
79fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        /* probably OOM */
80fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        LOGD("Failed allocating array of %d strings\n", count);
81364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        assert(dvmCheckException(self));
82fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        return NULL;
83fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    }
84fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
85fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    /*
86fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden     * Create the individual String objects and add them to the array.
87fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden     */
88fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    size_t i;
89fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    for (i = 0; i < count; i++) {
90364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        Object *str =
91364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes            (Object *)dvmCreateStringFromCstr(strings[i]);
92364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        if (str == NULL) {
93fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden            /* probably OOM; drop out now */
9481f3ebe03cd33c9003641084bece0604ee68bf88Barry Hayes            assert(dvmCheckException(self));
9531513e18a4be66463de110ce041a61b81c3f1367Andy McFadden            dvmReleaseTrackedAlloc((Object*)stringArray, self);
96fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden            return NULL;
97fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        }
98364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        dvmSetObjectArrayElement(stringArray, i, str);
9931513e18a4be66463de110ce041a61b81c3f1367Andy McFadden        /* stored in tracked array, okay to release */
100364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        dvmReleaseTrackedAlloc(str, self);
101fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    }
102fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
10331513e18a4be66463de110ce041a61b81c3f1367Andy McFadden    dvmReleaseTrackedAlloc((Object*)stringArray, self);
104fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    return stringArray;
105fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden}
106fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
107fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden/*
108fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden * static String[] getVmFeatureList()
109fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden *
110fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden * Return a set of strings describing available VM features (this is chiefly
111fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden * of interest to DDMS).  Some features may be controlled by compile-time
112fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden * or command-line flags.
113fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden */
114fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFaddenstatic void Dalvik_dalvik_system_VMDebug_getVmFeatureList(const u4* args,
115fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    JValue* pResult)
116fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden{
117fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    static const int MAX_FEATURE_COUNT = 10;
118fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    char* features[MAX_FEATURE_COUNT];
119fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    int idx = 0;
120fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
121fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    /* VM responds to DDMS method profiling requests */
122fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    features[idx++] = "method-trace-profiling";
1230171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    features[idx++] = "method-trace-profiling-streaming";
124fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden#ifdef WITH_HPROF
125fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    /* VM responds to DDMS heap dump requests */
126fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    features[idx++] = "hprof-heap-dump";
1276bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    features[idx++] = "hprof-heap-dump-streaming";
128fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden#endif
129fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
130fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    assert(idx <= MAX_FEATURE_COUNT);
131fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
132fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    LOGV("+++ sending up %d features\n", idx);
133fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    ArrayObject* arrayObj = convertStringArray(features, idx);
134fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    RETURN_PTR(arrayObj);       /* will be null on OOM */
135fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden}
136fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
137fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* These must match the values in dalvik.system.VMDebug.
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectenum {
141e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_ALLOCATED_OBJECTS      = 1<<0,
142e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_ALLOCATED_BYTES        = 1<<1,
143e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_FREED_OBJECTS          = 1<<2,
144e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_FREED_BYTES            = 1<<3,
145e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_GC_INVOCATIONS         = 1<<4,
146e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_CLASS_INIT_COUNT       = 1<<5,
147e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_CLASS_INIT_TIME        = 1<<6,
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if PROFILE_EXTERNAL_ALLOCATIONS
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_EXT_ALLOCATED_OBJECTS = 1<<12,
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_EXT_ALLOCATED_BYTES   = 1<<13,
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_EXT_FREED_OBJECTS     = 1<<14,
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_EXT_FREED_BYTES       = 1<<15,
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif // PROFILE_EXTERNAL_ALLOCATIONS
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_ALLOCATED_OBJECTS   = KIND_ALLOCATED_OBJECTS,
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_ALLOCATED_BYTES     = KIND_ALLOCATED_BYTES,
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_FREED_OBJECTS       = KIND_FREED_OBJECTS,
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_FREED_BYTES         = KIND_FREED_BYTES,
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_GC_INVOCATIONS      = KIND_GC_INVOCATIONS,
160e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_GLOBAL_CLASS_INIT_COUNT    = KIND_CLASS_INIT_COUNT,
161e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    KIND_GLOBAL_CLASS_INIT_TIME     = KIND_CLASS_INIT_TIME,
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if PROFILE_EXTERNAL_ALLOCATIONS
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_EXT_ALLOCATED_OBJECTS = KIND_EXT_ALLOCATED_OBJECTS,
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_EXT_ALLOCATED_BYTES = KIND_EXT_ALLOCATED_BYTES,
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_EXT_FREED_OBJECTS   = KIND_EXT_FREED_OBJECTS,
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_GLOBAL_EXT_FREED_BYTES     = KIND_EXT_FREED_BYTES,
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif // PROFILE_EXTERNAL_ALLOCATIONS
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_ALLOCATED_OBJECTS   = KIND_ALLOCATED_OBJECTS << 16,
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_ALLOCATED_BYTES     = KIND_ALLOCATED_BYTES << 16,
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_FREED_OBJECTS       = KIND_FREED_OBJECTS << 16,
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_FREED_BYTES         = KIND_FREED_BYTES << 16,
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if PROFILE_EXTERNAL_ALLOCATIONS
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_EXT_ALLOCATED_OBJECTS = KIND_EXT_ALLOCATED_OBJECTS << 16,
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_EXT_ALLOCATED_BYTES = KIND_EXT_ALLOCATED_BYTES << 16,
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_EXT_FREED_OBJECTS   = KIND_EXT_FREED_OBJECTS << 16,
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_EXT_FREED_BYTES     = KIND_EXT_FREED_BYTES << 16,
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif // PROFILE_EXTERNAL_ALLOCATIONS
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    KIND_THREAD_GC_INVOCATIONS      = KIND_GC_INVOCATIONS << 16,
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO: failedAllocCount, failedAllocSize
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define KIND_ALL_COUNTS 0xffffffff
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Zero out the specified fields.
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void clearAllocProfStateFields(AllocProfState *allocProf,
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    unsigned int kinds)
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_ALLOCATED_OBJECTS) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->allocCount = 0;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_ALLOCATED_BYTES) {
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->allocSize = 0;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_FREED_OBJECTS) {
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->freeCount = 0;
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_FREED_BYTES) {
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->freeSize = 0;
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_GC_INVOCATIONS) {
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->gcCount = 0;
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
207e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    if (kinds & KIND_CLASS_INIT_COUNT) {
208e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        allocProf->classInitCount = 0;
209e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    }
210e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    if (kinds & KIND_CLASS_INIT_TIME) {
211e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        allocProf->classInitTime = 0;
212e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    }
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if PROFILE_EXTERNAL_ALLOCATIONS
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_EXT_ALLOCATED_OBJECTS) {
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->externalAllocCount = 0;
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_EXT_ALLOCATED_BYTES) {
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->externalAllocSize = 0;
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_EXT_FREED_OBJECTS) {
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->externalFreeCount = 0;
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kinds & KIND_EXT_FREED_BYTES) {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf->externalFreeSize = 0;
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif // PROFILE_EXTERNAL_ALLOCATIONS
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void startAllocCounting()
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reset the counters and enable counting.
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: this currently only resets the per-thread counters for the current
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thread.  If we actually start using the per-thread counters we'll
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * probably want to fix this.
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_startAllocCounting(const u4* args,
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clearAllocProfStateFields(&gDvm.allocProf, KIND_ALL_COUNTS);
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clearAllocProfStateFields(&dvmThreadSelf()->allocProf, KIND_ALL_COUNTS);
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmStartAllocCounting();
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public static void stopAllocCounting()
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_stopAllocCounting(const u4* args,
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmStopAllocCounting();
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * private static int getAllocCount(int kind)
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_getAllocCount(const u4* args,
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    AllocProfState *allocProf;
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    unsigned int kind = args[0];
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (kind < (1<<16)) {
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf = &gDvm.allocProf;
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        allocProf = &dvmThreadSelf()->allocProf;
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        kind >>= 16;
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (kind) {
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_ALLOCATED_OBJECTS:
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->allocCount;
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_ALLOCATED_BYTES:
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->allocSize;
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_FREED_OBJECTS:
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->freeCount;
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_FREED_BYTES:
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->freeSize;
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_GC_INVOCATIONS:
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->gcCount;
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
291e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    case KIND_CLASS_INIT_COUNT:
292e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        pResult->i = allocProf->classInitCount;
293e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        break;
294e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden    case KIND_CLASS_INIT_TIME:
295e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        /* convert nsec to usec, reduce to 32 bits */
296e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        pResult->i = (int) (allocProf->classInitTime / 1000);
297e15a8eb2653da80c1c3816ddce8186746b57b4a3Andy McFadden        break;
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if PROFILE_EXTERNAL_ALLOCATIONS
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_EXT_ALLOCATED_OBJECTS:
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->externalAllocCount;
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_EXT_ALLOCATED_BYTES:
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->externalAllocSize;
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_EXT_FREED_OBJECTS:
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->externalFreeCount;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case KIND_EXT_FREED_BYTES:
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = allocProf->externalFreeSize;
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif // PROFILE_EXTERNAL_ALLOCATIONS
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pResult->i = -1;
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public static void resetAllocCount(int kinds)
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_resetAllocCount(const u4* args,
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    unsigned int kinds = args[0];
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clearAllocProfStateFields(&gDvm.allocProf, kinds & 0xffff);
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clearAllocProfStateFields(&dvmThreadSelf()->allocProf, kinds >> 16);
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
3310171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * static void startMethodTracingNative(String traceFileName,
3320171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden *     FileDescriptor fd, int bufferSize, int flags)
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Start method trace profiling.
3350171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden *
3360171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * If both "traceFileName" and "fd" are null, the result will be sent
3370171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * directly to DDMS.  (The non-DDMS versions of the calls are expected
3380171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * to enforce non-NULL filenames.)
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
3400171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenstatic void Dalvik_dalvik_system_VMDebug_startMethodTracingNative(const u4* args,
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* traceFileStr = (StringObject*) args[0];
3444b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    Object* traceFd = (Object*) args[1];
3450f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn    int bufferSize = args[2];
3460f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn    int flags = args[3];
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (bufferSize == 0) {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Default to 8MB per the documentation.
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bufferSize = 8 * 1024 * 1024;
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3530171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    if (bufferSize < 1024) {
3540f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn        dvmThrowException("Ljava/lang/IllegalArgumentException;", NULL);
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RETURN_VOID();
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3580171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    char* traceFileName = NULL;
3590171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    if (traceFileStr != NULL)
3600171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden        traceFileName = dvmCreateCstrFromString(traceFileStr);
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3620f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn    int fd = -1;
3630f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn    if (traceFd != NULL) {
3644b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        int origFd = getFileDescriptor(traceFd);
3654b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        if (origFd < 0)
3660f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn            RETURN_VOID();
3674b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden
3684b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        fd = dup(origFd);
3690171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden        if (fd < 0) {
3700171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden            dvmThrowExceptionFmt("Ljava/lang/RuntimeException;",
3714b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden                "dup(%d) failed: %s", origFd, strerror(errno));
3720171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden            RETURN_VOID();
3730171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden        }
3740f0ae023a3a53f7c9e254283b50a0099781acb79Dianne Hackborn    }
375de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
3760171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    dvmMethodTraceStart(traceFileName != NULL ? traceFileName : "[DDMS]",
3770171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden        fd, bufferSize, flags, (traceFileName == NULL && fd == -1));
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(traceFileName);
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
38399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * static boolean isMethodTracingActive()
38499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
38599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Determine whether method tracing is currently active.
38699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
38799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_isMethodTracingActive(const u4* args,
38899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    JValue* pResult)
38999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project{
39099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    UNUSED_PARAMETER(args);
39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
39299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    RETURN_BOOLEAN(dvmIsMethodTraceActive());
39399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project}
39499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
39599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void stopMethodTracing()
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stop method tracing.
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_stopMethodTracing(const u4* args,
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmMethodTraceStop();
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void startEmulatorTracing()
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Start sending method trace info to the emulator.
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_startEmulatorTracing(const u4* args,
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmEmulatorTraceStart();
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void stopEmulatorTracing()
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Start sending method trace info to the emulator.
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_stopEmulatorTracing(const u4* args,
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmEmulatorTraceStop();
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static int setAllocationLimit(int limit)
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the current allocation limit in this thread.  Return the previous
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value.
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_setAllocationLimit(const u4* args,
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(WITH_ALLOC_LIMITS)
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.checkAllocLimits = true;
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Thread* self = dvmThreadSelf();
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int newLimit = args[0];
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int oldLimit = self->allocLimit;
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (newLimit < -1) {
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("WARNING: bad limit request (%d)\n", newLimit);
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newLimit = -1;
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    self->allocLimit = newLimit;
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_INT(oldLimit);
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_INT(-1);
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static int setGlobalAllocationLimit(int limit)
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set the allocation limit for this process.  Returns the previous value.
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_setGlobalAllocationLimit(const u4* args,
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(WITH_ALLOC_LIMITS)
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.checkAllocLimits = true;
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int newLimit = args[0];
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int oldLimit = gDvm.allocationLimit;
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (newLimit < -1 || newLimit > 0) {
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("WARNING: bad limit request (%d)\n", newLimit);
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newLimit = -1;
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO: should use an atomic swap here
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.allocationLimit = newLimit;
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_INT(oldLimit);
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_INT(-1);
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static boolean isDebuggerConnected()
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if a debugger is attached.
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_isDebuggerConnected(const u4* args,
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_BOOLEAN(dvmDbgIsDebuggerConnected());
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static boolean isDebuggingEnabled()
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" if debugging is enabled.
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_isDebuggingEnabled(const u4* args,
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_BOOLEAN(gDvm.jdwpConfigured);
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static long lastDebuggerActivity()
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the time, in msec, since we last had an interaction with the
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger (send or receive).
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_lastDebuggerActivity(const u4* args,
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_LONG(dvmDbgLastDebuggerActivity());
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void startInstructionCounting()
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_startInstructionCounting(const u4* args,
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmStartInstructionCounting();
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void stopInstructionCounting()
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_stopInstructionCounting(const u4* args,
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmStopInstructionCounting();
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static boolean getInstructionCount(int[] counts)
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grab a copy of the global instruction count array.
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since the instruction counts aren't synchronized, we use sched_yield
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to improve our chances of finishing without contention.  (Only makes
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sense on a uniprocessor.)
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_getInstructionCount(const u4* args,
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ArrayObject* countArray = (ArrayObject*) args[0];
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int* storage;
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    storage = (int*) countArray->contents;
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    sched_yield();
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memcpy(storage, gDvm.executedInstrCounts,
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        kNumDalvikInstructions * sizeof(int));
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static boolean resetInstructionCount()
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reset the instruction count array.
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_resetInstructionCount(const u4* args,
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    sched_yield();
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(gDvm.executedInstrCounts, 0, kNumDalvikInstructions * sizeof(int));
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static void printLoadedClasses(int flags)
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump the list of loaded classes.
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_printLoadedClasses(const u4* args,
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int flags = args[0];
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmDumpAllClasses(flags);
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * static int getLoadedClassCount()
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the number of loaded classes
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_getLoadedClassCount(const u4* args,
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count;
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(args);
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    count = dvmGetNumLoadedClasses();
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_INT(count);
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the thread-specific CPU-time clock value for the current thread,
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or -1 if the feature isn't supported.
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos(const u4* args,
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jlong result;
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_CLOCKS
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct timespec now;
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = (jlong) (now.tv_sec*1000000000LL + now.tv_nsec);
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = (jlong) -1;
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_LONG(result);
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
6404b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden * static void dumpHprofData(String fileName, FileDescriptor fd)
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Cause "hprof" data to be dumped.  We can throw an IOException if an
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * error occurs during file handling.
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMDebug_dumpHprofData(const u4* args,
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JValue* pResult)
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef WITH_HPROF
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    StringObject* fileNameStr = (StringObject*) args[0];
6504b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    Object* fileDescriptor = (Object*) args[1];
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* fileName;
65299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    int result;
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6544b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    /*
6554b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden     * Only one of these may be NULL.
6564b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden     */
6574b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    if (fileNameStr == NULL && fileDescriptor == NULL) {
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmThrowException("Ljava/lang/NullPointerException;", NULL);
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RETURN_VOID();
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6624b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    if (fileNameStr != NULL) {
6634b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        fileName = dvmCreateCstrFromString(fileNameStr);
6644b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        if (fileName == NULL) {
6654b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden            /* unexpected -- malloc failure? */
6664b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden            dvmThrowException("Ljava/lang/RuntimeException;", "malloc failure?");
6674b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden            RETURN_VOID();
6684b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        }
6694b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    } else {
6704b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        fileName = strdup("[fd]");
6714b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    }
6724b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden
6734b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    int fd = -1;
6744b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    if (fileDescriptor != NULL) {
6754b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        fd = getFileDescriptor(fileDescriptor);
6764b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden        if (fd < 0)
6774b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden            RETURN_VOID();
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6804b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    result = hprofDumpHeap(fileName, fd, false);
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(fileName);
68299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
68399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    if (result != 0) {
68499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /* ideally we'd throw something more specific based on actual failure */
68599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        dvmThrowException("Ljava/lang/RuntimeException;",
68699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            "Failure during heap dump -- check log output for details");
68799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        RETURN_VOID();
68899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    }
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RETURN_VOID();
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6969faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden/*
6976bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * static void dumpHprofDataDdms()
6986bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden *
6996bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * Cause "hprof" data to be computed and sent directly to DDMS.
7006bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden */
7016bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFaddenstatic void Dalvik_dalvik_system_VMDebug_dumpHprofDataDdms(const u4* args,
7026bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    JValue* pResult)
7036bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden{
7046bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden#ifdef WITH_HPROF
7056bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    int result;
7066bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden
7074b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    result = hprofDumpHeap("[DDMS]", -1, true);
7086bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden
7096bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    if (result != 0) {
7106bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden        /* ideally we'd throw something more specific based on actual failure */
7116bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden        dvmThrowException("Ljava/lang/RuntimeException;",
7126bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden            "Failure during heap dump -- check log output for details");
7136bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden        RETURN_VOID();
7146bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    }
7156bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden#else
7166bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
7176bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden#endif
7186bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden
7196bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    RETURN_VOID();
7206bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden}
7216bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden
7226bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden/*
7239faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * static boolean cacheRegisterMap(String classAndMethodDescr)
7249faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden *
7259faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * If the specified class is loaded, and the named method exists, ensure
7269faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * that the method's register map is ready for use.  If the class/method
7279faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * cannot be found, nothing happens.
7289faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden *
7299faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * This can improve the zygote's sharing of compressed register maps.  Do
7309faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * this after class preloading.
7319faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden *
7329faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * Returns true if the register map is cached and ready, either as a result
7339faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * of this call or earlier activity.  Returns false if the class isn't loaded,
7349faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * if the method couldn't be found, or if the method has no register map.
7359faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden *
7369faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden * (Uncomment logs in dvmGetExpandedRegisterMap0() to gather stats.)
7379faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden */
7389faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFaddenstatic void Dalvik_dalvik_system_VMDebug_cacheRegisterMap(const u4* args,
7399faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    JValue* pResult)
7409faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden{
7419faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    StringObject* classAndMethodDescStr = (StringObject*) args[0];
7429faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    ClassObject* clazz;
7439faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    bool result = false;
7449faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7459faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    if (classAndMethodDescStr == NULL) {
7469faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        dvmThrowException("Ljava/lang/NullPointerException;", NULL);
7479faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        RETURN_VOID();
7489faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    }
7499faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7509faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    char* classAndMethodDesc = NULL;
7519faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7529faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    /*
7539faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     * Pick the string apart.  We have a local copy, so just modify it
7549faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     * in place.
7559faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     */
7569faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    classAndMethodDesc = dvmCreateCstrFromString(classAndMethodDescStr);
7579faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7589faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    char* methodName = strchr(classAndMethodDesc, '.');
7599faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    if (methodName == NULL) {
7609faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        dvmThrowException("Ljava/lang/RuntimeException;",
7619faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            "method name not found in string");
7629faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        RETURN_VOID();
7639faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    }
7649faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    *methodName++ = '\0';
7659faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7669faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    char* methodDescr = strchr(methodName, ':');
7679faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    if (methodDescr == NULL) {
7689faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        dvmThrowException("Ljava/lang/RuntimeException;",
7699faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            "method descriptor not found in string");
7709faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        RETURN_VOID();
7719faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    }
7729faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    *methodDescr++ = '\0';
7739faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7749faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    //LOGD("GOT: %s %s %s\n", classAndMethodDesc, methodName, methodDescr);
7759faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7769faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    /*
7779faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     * Find the class, but only if it's already loaded.
7789faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     */
7799faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    clazz = dvmLookupClass(classAndMethodDesc, NULL, false);
7809faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    if (clazz == NULL) {
7819faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        LOGD("Class %s not found in bootstrap loader\n", classAndMethodDesc);
7829faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        goto bail;
7839faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    }
7849faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7859faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    Method* method;
7869faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
7879faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    /*
7889faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     * Find the method, which could be virtual or direct, defined directly
7899faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     * or inherited.
7909faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden     */
7919faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    if (methodName[0] == '<') {
7929faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        /*
7939faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         * Constructor or class initializer.  Only need to examine the
7949faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         * "direct" list, and don't need to search up the class hierarchy.
7959faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         */
7969faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        method = dvmFindDirectMethodByDescriptor(clazz, methodName,
7979faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden                    methodDescr);
7989faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    } else {
7999faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        /*
8009faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         * Try both lists, and scan up the tree.
8019faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         */
8029faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        method = dvmFindVirtualMethodHierByDescriptor(clazz, methodName,
8039faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden                    methodDescr);
8049faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        if (method == NULL) {
8059faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            method = dvmFindDirectMethodHierByDescriptor(clazz, methodName,
8069faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden                        methodDescr);
8079faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        }
8089faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    }
8099faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
8109faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    if (method != NULL) {
8119faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        /*
8129faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         * Got it.  See if there's a register map here.
8139faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden         */
8149faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        const RegisterMap* pMap;
8159faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        pMap = dvmGetExpandedRegisterMap(method);
8169faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        if (pMap == NULL) {
8179faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            LOGV("No map for %s.%s %s\n",
8189faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden                classAndMethodDesc, methodName, methodDescr);
8199faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        } else {
8209faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            LOGV("Found map %s.%s %s\n",
8219faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden                classAndMethodDesc, methodName, methodDescr);
8229faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            result = true;
8239faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        }
8249faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    } else {
8259faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        LOGV("Unable to find %s.%s %s\n",
8269faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden            classAndMethodDesc, methodName, methodDescr);
8279faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    }
8289faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
8299faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFaddenbail:
8309faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    free(classAndMethodDesc);
8319faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    RETURN_BOOLEAN(result);
8329faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden}
8339faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden
834e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden/*
83592fa476a8802023b443af893817eb14fef18aaeaAndy McFadden * static void dumpReferenceTables()
83692fa476a8802023b443af893817eb14fef18aaeaAndy McFadden */
83792fa476a8802023b443af893817eb14fef18aaeaAndy McFaddenstatic void Dalvik_dalvik_system_VMDebug_dumpReferenceTables(const u4* args,
83892fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    JValue* pResult)
83992fa476a8802023b443af893817eb14fef18aaeaAndy McFadden{
84092fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    UNUSED_PARAMETER(args);
84192fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    UNUSED_PARAMETER(pResult);
84292fa476a8802023b443af893817eb14fef18aaeaAndy McFadden
84392fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    LOGI("--- reference table dump ---\n");
84492fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    dvmDumpJniReferenceTables();
84592fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    // could dump thread's internalLocalRefTable, probably not useful
84692fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    // ditto for thread's jniMonitorRefTable
84792fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    LOGI("---\n");
84892fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    RETURN_VOID();
84992fa476a8802023b443af893817eb14fef18aaeaAndy McFadden}
85092fa476a8802023b443af893817eb14fef18aaeaAndy McFadden
85192fa476a8802023b443af893817eb14fef18aaeaAndy McFadden/*
852e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden * static void crash()
853e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden *
854e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden * Dump the current thread's interpreted stack and abort the VM.  Useful
855e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden * for seeing both interpreted and native stack traces.
856e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden *
857e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden * (Might want to restrict this to debuggable processes as a security
858e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden * measure, or check SecurityManager.checkExit().)
859e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden */
860e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFaddenstatic void Dalvik_dalvik_system_VMDebug_crash(const u4* args,
861e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    JValue* pResult)
862e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden{
863e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    UNUSED_PARAMETER(args);
864e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    UNUSED_PARAMETER(pResult);
865e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden
866e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    LOGW("Crashing VM on request\n");
867e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    dvmDumpThread(dvmThreadSelf(), false);
868e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    dvmAbort();
869e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden}
870e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden
8717d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng/*
8727d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng * static void infopoint(int id)
8737d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng *
8747d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng * Provide a hook for gdb to hang to so that the VM can be stopped when
8757d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng * user-tagged source locations are being executed.
8767d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng */
8777d656ddd1ac67833e0331bb7cf92b7298b494762Ben Chengstatic void Dalvik_dalvik_system_VMDebug_infopoint(const u4* args,
8787d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng    JValue* pResult)
8797d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng{
8807d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng    gDvm.nativeDebuggerActive = true;
8817d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng
8827d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng    LOGD("VMDebug infopoint %d hit", args[0]);
8837d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng
8847d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng    gDvm.nativeDebuggerActive = false;
8857d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng    RETURN_VOID();
8867d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng}
8877d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng
888e0376ec0eaeb77686945080c89c300cff7506962Carl Shapirostatic void Dalvik_dalvik_system_VMDebug_countInstancesOfClass(const u4* args,
889e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro    JValue* pResult)
890e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro{
891e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro    ClassObject* clazz = (ClassObject*)args[0];
8926159ef4520073ae8e7ce7b7d1f7648b161a33302Carl Shapiro    bool countAssignable = args[1];
893e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro    if (clazz == NULL) {
894e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro        RETURN_LONG(0);
8956159ef4520073ae8e7ce7b7d1f7648b161a33302Carl Shapiro    }
8966159ef4520073ae8e7ce7b7d1f7648b161a33302Carl Shapiro    if (countAssignable) {
8976159ef4520073ae8e7ce7b7d1f7648b161a33302Carl Shapiro        size_t count = dvmCountAssignableInstancesOfClass(clazz);
8986159ef4520073ae8e7ce7b7d1f7648b161a33302Carl Shapiro        RETURN_LONG((long long)count);
899e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro    } else {
90041eb6e988193a1c6b331c7c208bf8dd74f96d773Carl Shapiro        size_t count = dvmCountInstancesOfClass(clazz);
901e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro        RETURN_LONG((long long)count);
902e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro    }
903e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro}
904e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst DalvikNativeMethod dvm_dalvik_system_VMDebug[] = {
906fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden    { "getVmFeatureList",           "()[Ljava/lang/String;",
907fd52c6526bf84c24ee6dec5ca6822c3a78bbd4a3Andy McFadden        Dalvik_dalvik_system_VMDebug_getVmFeatureList },
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "getAllocCount",              "(I)I",
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_getAllocCount },
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "resetAllocCount",            "(I)V",
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_resetAllocCount },
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "startAllocCounting",         "()V",
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_startAllocCounting },
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "stopAllocCounting",          "()V",
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_stopAllocCounting },
9160171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden    { "startMethodTracingNative",   "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V",
9170171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden        Dalvik_dalvik_system_VMDebug_startMethodTracingNative },
91899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    { "isMethodTracingActive",      "()Z",
91999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        Dalvik_dalvik_system_VMDebug_isMethodTracingActive },
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "stopMethodTracing",          "()V",
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_stopMethodTracing },
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "startEmulatorTracing",       "()V",
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_startEmulatorTracing },
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "stopEmulatorTracing",        "()V",
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_stopEmulatorTracing },
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "setAllocationLimit",         "(I)I",
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_setAllocationLimit },
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "setGlobalAllocationLimit",   "(I)I",
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_setGlobalAllocationLimit },
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "startInstructionCounting",   "()V",
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_startInstructionCounting },
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "stopInstructionCounting",    "()V",
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_stopInstructionCounting },
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "resetInstructionCount",      "()V",
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_resetInstructionCount },
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "getInstructionCount",        "([I)V",
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_getInstructionCount },
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "isDebuggerConnected",        "()Z",
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_isDebuggerConnected },
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "isDebuggingEnabled",         "()Z",
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_isDebuggingEnabled },
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "lastDebuggerActivity",       "()J",
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_lastDebuggerActivity },
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "printLoadedClasses",         "(I)V",
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_printLoadedClasses },
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "getLoadedClassCount",        "()I",
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_getLoadedClassCount },
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { "threadCpuTimeNanos",         "()J",
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos },
9504b851a75f7712086a9fc4427f68c99b83725f37dAndy McFadden    { "dumpHprofData",              "(Ljava/lang/String;Ljava/io/FileDescriptor;)V",
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Dalvik_dalvik_system_VMDebug_dumpHprofData },
9526bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden    { "dumpHprofDataDdms",          "()V",
9536bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden        Dalvik_dalvik_system_VMDebug_dumpHprofDataDdms },
9549faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden    { "cacheRegisterMap",           "(Ljava/lang/String;)Z",
9559faa9e6a7df9a5b9ef7c8e9d5c07d2a050c319d3Andy McFadden        Dalvik_dalvik_system_VMDebug_cacheRegisterMap },
95692fa476a8802023b443af893817eb14fef18aaeaAndy McFadden    { "dumpReferenceTables",        "()V",
95792fa476a8802023b443af893817eb14fef18aaeaAndy McFadden        Dalvik_dalvik_system_VMDebug_dumpReferenceTables },
958e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden    { "crash",                      "()V",
959e9efb8a44202c814b0ebdc16fbab1f754451cd38Andy McFadden        Dalvik_dalvik_system_VMDebug_crash },
9607d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng    { "infopoint",                 "(I)V",
9617d656ddd1ac67833e0331bb7cf92b7298b494762Ben Cheng        Dalvik_dalvik_system_VMDebug_infopoint },
9626159ef4520073ae8e7ce7b7d1f7648b161a33302Carl Shapiro    { "countInstancesOfClass",     "(Ljava/lang/Class;Z)J",
963e0376ec0eaeb77686945080c89c300cff7506962Carl Shapiro        Dalvik_dalvik_system_VMDebug_countInstancesOfClass },
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    { NULL, NULL, NULL },
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
966