• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * dalvik.system.VMDebug
19  */
20 #include "Dalvik.h"
21 #include "native/InternalNativePriv.h"
22 
23 
24 #ifdef WITH_PROFILER
25 /* These must match the values in dalvik.system.VMDebug.
26  */
27 enum {
28     KIND_ALLOCATED_OBJECTS = 1<<0,
29     KIND_ALLOCATED_BYTES   = 1<<1,
30     KIND_FREED_OBJECTS     = 1<<2,
31     KIND_FREED_BYTES       = 1<<3,
32     KIND_GC_INVOCATIONS    = 1<<4,
33 #if PROFILE_EXTERNAL_ALLOCATIONS
34     KIND_EXT_ALLOCATED_OBJECTS = 1<<12,
35     KIND_EXT_ALLOCATED_BYTES   = 1<<13,
36     KIND_EXT_FREED_OBJECTS     = 1<<14,
37     KIND_EXT_FREED_BYTES       = 1<<15,
38 #endif // PROFILE_EXTERNAL_ALLOCATIONS
39 
40     KIND_GLOBAL_ALLOCATED_OBJECTS   = KIND_ALLOCATED_OBJECTS,
41     KIND_GLOBAL_ALLOCATED_BYTES     = KIND_ALLOCATED_BYTES,
42     KIND_GLOBAL_FREED_OBJECTS       = KIND_FREED_OBJECTS,
43     KIND_GLOBAL_FREED_BYTES         = KIND_FREED_BYTES,
44     KIND_GLOBAL_GC_INVOCATIONS      = KIND_GC_INVOCATIONS,
45 #if PROFILE_EXTERNAL_ALLOCATIONS
46     KIND_GLOBAL_EXT_ALLOCATED_OBJECTS = KIND_EXT_ALLOCATED_OBJECTS,
47     KIND_GLOBAL_EXT_ALLOCATED_BYTES = KIND_EXT_ALLOCATED_BYTES,
48     KIND_GLOBAL_EXT_FREED_OBJECTS   = KIND_EXT_FREED_OBJECTS,
49     KIND_GLOBAL_EXT_FREED_BYTES     = KIND_EXT_FREED_BYTES,
50 #endif // PROFILE_EXTERNAL_ALLOCATIONS
51 
52     KIND_THREAD_ALLOCATED_OBJECTS   = KIND_ALLOCATED_OBJECTS << 16,
53     KIND_THREAD_ALLOCATED_BYTES     = KIND_ALLOCATED_BYTES << 16,
54     KIND_THREAD_FREED_OBJECTS       = KIND_FREED_OBJECTS << 16,
55     KIND_THREAD_FREED_BYTES         = KIND_FREED_BYTES << 16,
56 #if PROFILE_EXTERNAL_ALLOCATIONS
57     KIND_THREAD_EXT_ALLOCATED_OBJECTS = KIND_EXT_ALLOCATED_OBJECTS << 16,
58     KIND_THREAD_EXT_ALLOCATED_BYTES = KIND_EXT_ALLOCATED_BYTES << 16,
59     KIND_THREAD_EXT_FREED_OBJECTS   = KIND_EXT_FREED_OBJECTS << 16,
60     KIND_THREAD_EXT_FREED_BYTES     = KIND_EXT_FREED_BYTES << 16,
61 #endif // PROFILE_EXTERNAL_ALLOCATIONS
62     KIND_THREAD_GC_INVOCATIONS      = KIND_GC_INVOCATIONS << 16,
63 
64     // TODO: failedAllocCount, failedAllocSize
65 };
66 
67 #define KIND_ALL_COUNTS 0xffffffff
68 
69 /*
70  * Zero out the specified fields.
71  */
clearAllocProfStateFields(AllocProfState * allocProf,unsigned int kinds)72 static void clearAllocProfStateFields(AllocProfState *allocProf,
73     unsigned int kinds)
74 {
75     if (kinds & KIND_ALLOCATED_OBJECTS) {
76         allocProf->allocCount = 0;
77     }
78     if (kinds & KIND_ALLOCATED_BYTES) {
79         allocProf->allocSize = 0;
80     }
81     if (kinds & KIND_FREED_OBJECTS) {
82         allocProf->freeCount = 0;
83     }
84     if (kinds & KIND_FREED_BYTES) {
85         allocProf->freeSize = 0;
86     }
87     if (kinds & KIND_GC_INVOCATIONS) {
88         allocProf->gcCount = 0;
89     }
90 #if PROFILE_EXTERNAL_ALLOCATIONS
91     if (kinds & KIND_EXT_ALLOCATED_OBJECTS) {
92         allocProf->externalAllocCount = 0;
93     }
94     if (kinds & KIND_EXT_ALLOCATED_BYTES) {
95         allocProf->externalAllocSize = 0;
96     }
97     if (kinds & KIND_EXT_FREED_OBJECTS) {
98         allocProf->externalFreeCount = 0;
99     }
100     if (kinds & KIND_EXT_FREED_BYTES) {
101         allocProf->externalFreeSize = 0;
102     }
103 #endif // PROFILE_EXTERNAL_ALLOCATIONS
104 }
105 #endif
106 
107 /*
108  * static void startAllocCounting()
109  *
110  * Reset the counters and enable counting.
111  *
112  * TODO: this currently only resets the per-thread counters for the current
113  * thread.  If we actually start using the per-thread counters we'll
114  * probably want to fix this.
115  */
Dalvik_dalvik_system_VMDebug_startAllocCounting(const u4 * args,JValue * pResult)116 static void Dalvik_dalvik_system_VMDebug_startAllocCounting(const u4* args,
117     JValue* pResult)
118 {
119     UNUSED_PARAMETER(args);
120 
121 #ifdef WITH_PROFILER
122     clearAllocProfStateFields(&gDvm.allocProf, KIND_ALL_COUNTS);
123     clearAllocProfStateFields(&dvmThreadSelf()->allocProf, KIND_ALL_COUNTS);
124     dvmStartAllocCounting();
125 #endif
126     RETURN_VOID();
127 }
128 
129 /*
130  * public static void stopAllocCounting()
131  */
Dalvik_dalvik_system_VMDebug_stopAllocCounting(const u4 * args,JValue * pResult)132 static void Dalvik_dalvik_system_VMDebug_stopAllocCounting(const u4* args,
133     JValue* pResult)
134 {
135     UNUSED_PARAMETER(args);
136 
137 #ifdef WITH_PROFILER
138     dvmStopAllocCounting();
139 #endif
140     RETURN_VOID();
141 }
142 
143 /*
144  * private static int getAllocCount(int kind)
145  */
Dalvik_dalvik_system_VMDebug_getAllocCount(const u4 * args,JValue * pResult)146 static void Dalvik_dalvik_system_VMDebug_getAllocCount(const u4* args,
147     JValue* pResult)
148 {
149 #ifdef WITH_PROFILER
150     AllocProfState *allocProf;
151     unsigned int kind = args[0];
152     if (kind < (1<<16)) {
153         allocProf = &gDvm.allocProf;
154     } else {
155         allocProf = &dvmThreadSelf()->allocProf;
156         kind >>= 16;
157     }
158     switch (kind) {
159     case KIND_ALLOCATED_OBJECTS:
160         pResult->i = allocProf->allocCount;
161         break;
162     case KIND_ALLOCATED_BYTES:
163         pResult->i = allocProf->allocSize;
164         break;
165     case KIND_FREED_OBJECTS:
166         pResult->i = allocProf->freeCount;
167         break;
168     case KIND_FREED_BYTES:
169         pResult->i = allocProf->freeSize;
170         break;
171     case KIND_GC_INVOCATIONS:
172         pResult->i = allocProf->gcCount;
173         break;
174 #if PROFILE_EXTERNAL_ALLOCATIONS
175     case KIND_EXT_ALLOCATED_OBJECTS:
176         pResult->i = allocProf->externalAllocCount;
177         break;
178     case KIND_EXT_ALLOCATED_BYTES:
179         pResult->i = allocProf->externalAllocSize;
180         break;
181     case KIND_EXT_FREED_OBJECTS:
182         pResult->i = allocProf->externalFreeCount;
183         break;
184     case KIND_EXT_FREED_BYTES:
185         pResult->i = allocProf->externalFreeSize;
186         break;
187 #endif // PROFILE_EXTERNAL_ALLOCATIONS
188     default:
189         assert(false);
190         pResult->i = -1;
191     }
192 #else
193     RETURN_INT(-1);
194 #endif
195 }
196 
197 /*
198  * public static void resetAllocCount(int kinds)
199  */
Dalvik_dalvik_system_VMDebug_resetAllocCount(const u4 * args,JValue * pResult)200 static void Dalvik_dalvik_system_VMDebug_resetAllocCount(const u4* args,
201     JValue* pResult)
202 {
203 #ifdef WITH_PROFILER
204     unsigned int kinds = args[0];
205     clearAllocProfStateFields(&gDvm.allocProf, kinds & 0xffff);
206     clearAllocProfStateFields(&dvmThreadSelf()->allocProf, kinds >> 16);
207 #endif
208     RETURN_VOID();
209 }
210 
211 /*
212  * static void startMethodTracing(String traceFileName, java.io.FileDescriptor,
213  *     int bufferSize, int flags)
214  *
215  * Start method trace profiling.
216  */
Dalvik_dalvik_system_VMDebug_startMethodTracing(const u4 * args,JValue * pResult)217 static void Dalvik_dalvik_system_VMDebug_startMethodTracing(const u4* args,
218     JValue* pResult)
219 {
220 #ifdef WITH_PROFILER
221     StringObject* traceFileStr = (StringObject*) args[0];
222     DataObject* traceFd = (DataObject*) args[1];
223     int bufferSize = args[2];
224     int flags = args[3];
225     char* traceFileName;
226 
227     if (bufferSize == 0) {
228         // Default to 8MB per the documentation.
229         bufferSize = 8 * 1024 * 1024;
230     }
231 
232     if (traceFileStr == NULL || bufferSize < 1024) {
233         dvmThrowException("Ljava/lang/IllegalArgumentException;", NULL);
234         RETURN_VOID();
235     }
236 
237     traceFileName = dvmCreateCstrFromString(traceFileStr);
238 
239     int fd = -1;
240     if (traceFd != NULL) {
241         InstField* field = dvmFindInstanceField(traceFd->obj.clazz, "descriptor", "I");
242         if (field == NULL) {
243             dvmThrowException("Ljava/lang/NoSuchFieldException;",
244                 "No FileDescriptor.descriptor field");
245             RETURN_VOID();
246         }
247         fd = dup(dvmGetFieldInt(&traceFd->obj, field->byteOffset));
248     }
249 
250     dvmMethodTraceStart(traceFileName, fd, bufferSize, flags);
251     free(traceFileName);
252 #else
253     // throw exception?
254 #endif
255     RETURN_VOID();
256 }
257 
258 /*
259  * static boolean isMethodTracingActive()
260  *
261  * Determine whether method tracing is currently active.
262  */
Dalvik_dalvik_system_VMDebug_isMethodTracingActive(const u4 * args,JValue * pResult)263 static void Dalvik_dalvik_system_VMDebug_isMethodTracingActive(const u4* args,
264     JValue* pResult)
265 {
266     UNUSED_PARAMETER(args);
267 
268 #ifdef WITH_PROFILER
269     RETURN_BOOLEAN(dvmIsMethodTraceActive());
270 #else
271     RETURN_BOOLEAN(false);
272 #endif
273 }
274 
275 /*
276  * static void stopMethodTracing()
277  *
278  * Stop method tracing.
279  */
Dalvik_dalvik_system_VMDebug_stopMethodTracing(const u4 * args,JValue * pResult)280 static void Dalvik_dalvik_system_VMDebug_stopMethodTracing(const u4* args,
281     JValue* pResult)
282 {
283     UNUSED_PARAMETER(args);
284 
285 #ifdef WITH_PROFILER
286     dvmMethodTraceStop();
287 #else
288     // throw exception?
289 #endif
290     RETURN_VOID();
291 }
292 
293 /*
294  * static void startEmulatorTracing()
295  *
296  * Start sending method trace info to the emulator.
297  */
Dalvik_dalvik_system_VMDebug_startEmulatorTracing(const u4 * args,JValue * pResult)298 static void Dalvik_dalvik_system_VMDebug_startEmulatorTracing(const u4* args,
299     JValue* pResult)
300 {
301     UNUSED_PARAMETER(args);
302 
303 #ifdef WITH_PROFILER
304     dvmEmulatorTraceStart();
305 #else
306     // throw exception?
307 #endif
308     RETURN_VOID();
309 }
310 
311 /*
312  * static void stopEmulatorTracing()
313  *
314  * Start sending method trace info to the emulator.
315  */
Dalvik_dalvik_system_VMDebug_stopEmulatorTracing(const u4 * args,JValue * pResult)316 static void Dalvik_dalvik_system_VMDebug_stopEmulatorTracing(const u4* args,
317     JValue* pResult)
318 {
319     UNUSED_PARAMETER(args);
320 
321 #ifdef WITH_PROFILER
322     dvmEmulatorTraceStop();
323 #else
324     // throw exception?
325 #endif
326     RETURN_VOID();
327 }
328 
329 /*
330  * static int setAllocationLimit(int limit)
331  *
332  * Set the current allocation limit in this thread.  Return the previous
333  * value.
334  */
Dalvik_dalvik_system_VMDebug_setAllocationLimit(const u4 * args,JValue * pResult)335 static void Dalvik_dalvik_system_VMDebug_setAllocationLimit(const u4* args,
336     JValue* pResult)
337 {
338 #if defined(WITH_ALLOC_LIMITS)
339     gDvm.checkAllocLimits = true;
340 
341     Thread* self = dvmThreadSelf();
342     int newLimit = args[0];
343     int oldLimit = self->allocLimit;
344 
345     if (newLimit < -1) {
346         LOGE("WARNING: bad limit request (%d)\n", newLimit);
347         newLimit = -1;
348     }
349     self->allocLimit = newLimit;
350     RETURN_INT(oldLimit);
351 #else
352     UNUSED_PARAMETER(args);
353     RETURN_INT(-1);
354 #endif
355 }
356 
357 /*
358  * static int setGlobalAllocationLimit(int limit)
359  *
360  * Set the allocation limit for this process.  Returns the previous value.
361  */
Dalvik_dalvik_system_VMDebug_setGlobalAllocationLimit(const u4 * args,JValue * pResult)362 static void Dalvik_dalvik_system_VMDebug_setGlobalAllocationLimit(const u4* args,
363     JValue* pResult)
364 {
365 #if defined(WITH_ALLOC_LIMITS)
366     gDvm.checkAllocLimits = true;
367 
368     int newLimit = args[0];
369     int oldLimit = gDvm.allocationLimit;
370 
371     if (newLimit < -1 || newLimit > 0) {
372         LOGE("WARNING: bad limit request (%d)\n", newLimit);
373         newLimit = -1;
374     }
375     // TODO: should use an atomic swap here
376     gDvm.allocationLimit = newLimit;
377     RETURN_INT(oldLimit);
378 #else
379     UNUSED_PARAMETER(args);
380     RETURN_INT(-1);
381 #endif
382 }
383 
384 /*
385  * static boolean isDebuggerConnected()
386  *
387  * Returns "true" if a debugger is attached.
388  */
Dalvik_dalvik_system_VMDebug_isDebuggerConnected(const u4 * args,JValue * pResult)389 static void Dalvik_dalvik_system_VMDebug_isDebuggerConnected(const u4* args,
390     JValue* pResult)
391 {
392     UNUSED_PARAMETER(args);
393 
394     RETURN_BOOLEAN(dvmDbgIsDebuggerConnected());
395 }
396 
397 /*
398  * static boolean isDebuggingEnabled()
399  *
400  * Returns "true" if debugging is enabled.
401  */
Dalvik_dalvik_system_VMDebug_isDebuggingEnabled(const u4 * args,JValue * pResult)402 static void Dalvik_dalvik_system_VMDebug_isDebuggingEnabled(const u4* args,
403     JValue* pResult)
404 {
405     UNUSED_PARAMETER(args);
406 
407     RETURN_BOOLEAN(gDvm.jdwpConfigured);
408 }
409 
410 /*
411  * static long lastDebuggerActivity()
412  *
413  * Returns the time, in msec, since we last had an interaction with the
414  * debugger (send or receive).
415  */
Dalvik_dalvik_system_VMDebug_lastDebuggerActivity(const u4 * args,JValue * pResult)416 static void Dalvik_dalvik_system_VMDebug_lastDebuggerActivity(const u4* args,
417     JValue* pResult)
418 {
419     UNUSED_PARAMETER(args);
420 
421     RETURN_LONG(dvmDbgLastDebuggerActivity());
422 }
423 
424 /*
425  * static void startInstructionCounting()
426  */
Dalvik_dalvik_system_VMDebug_startInstructionCounting(const u4 * args,JValue * pResult)427 static void Dalvik_dalvik_system_VMDebug_startInstructionCounting(const u4* args,
428     JValue* pResult)
429 {
430 #if defined(WITH_PROFILER)
431     dvmStartInstructionCounting();
432 #else
433     dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
434 #endif
435     RETURN_VOID();
436 }
437 
438 /*
439  * static void stopInstructionCounting()
440  */
Dalvik_dalvik_system_VMDebug_stopInstructionCounting(const u4 * args,JValue * pResult)441 static void Dalvik_dalvik_system_VMDebug_stopInstructionCounting(const u4* args,
442     JValue* pResult)
443 {
444 #if defined(WITH_PROFILER)
445     dvmStopInstructionCounting();
446 #else
447     dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
448 #endif
449     RETURN_VOID();
450 }
451 
452 /*
453  * static boolean getInstructionCount(int[] counts)
454  *
455  * Grab a copy of the global instruction count array.
456  *
457  * Since the instruction counts aren't synchronized, we use sched_yield
458  * to improve our chances of finishing without contention.  (Only makes
459  * sense on a uniprocessor.)
460  */
Dalvik_dalvik_system_VMDebug_getInstructionCount(const u4 * args,JValue * pResult)461 static void Dalvik_dalvik_system_VMDebug_getInstructionCount(const u4* args,
462     JValue* pResult)
463 {
464 #if defined(WITH_PROFILER)
465     ArrayObject* countArray = (ArrayObject*) args[0];
466     int* storage;
467 
468     storage = (int*) countArray->contents;
469     sched_yield();
470     memcpy(storage, gDvm.executedInstrCounts,
471         kNumDalvikInstructions * sizeof(int));
472 #else
473     dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
474 #endif
475     RETURN_VOID();
476 }
477 
478 /*
479  * static boolean resetInstructionCount()
480  *
481  * Reset the instruction count array.
482  */
Dalvik_dalvik_system_VMDebug_resetInstructionCount(const u4 * args,JValue * pResult)483 static void Dalvik_dalvik_system_VMDebug_resetInstructionCount(const u4* args,
484     JValue* pResult)
485 {
486 #if defined(WITH_PROFILER)
487     sched_yield();
488     memset(gDvm.executedInstrCounts, 0, kNumDalvikInstructions * sizeof(int));
489 #else
490     dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
491 #endif
492     RETURN_VOID();
493 }
494 
495 /*
496  * static void printLoadedClasses(int flags)
497  *
498  * Dump the list of loaded classes.
499  */
Dalvik_dalvik_system_VMDebug_printLoadedClasses(const u4 * args,JValue * pResult)500 static void Dalvik_dalvik_system_VMDebug_printLoadedClasses(const u4* args,
501     JValue* pResult)
502 {
503     int flags = args[0];
504 
505     dvmDumpAllClasses(flags);
506 
507     RETURN_VOID();
508 }
509 
510 /*
511  * static int getLoadedClassCount()
512  *
513  * Return the number of loaded classes
514  */
Dalvik_dalvik_system_VMDebug_getLoadedClassCount(const u4 * args,JValue * pResult)515 static void Dalvik_dalvik_system_VMDebug_getLoadedClassCount(const u4* args,
516     JValue* pResult)
517 {
518     int count;
519 
520     UNUSED_PARAMETER(args);
521 
522     count = dvmGetNumLoadedClasses();
523 
524     RETURN_INT(count);
525 }
526 
527 /*
528  * Returns the thread-specific CPU-time clock value for the current thread,
529  * or -1 if the feature isn't supported.
530  */
Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos(const u4 * args,JValue * pResult)531 static void Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos(const u4* args,
532     JValue* pResult)
533 {
534     jlong result;
535 
536 #ifdef HAVE_POSIX_CLOCKS
537     struct timespec now;
538     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
539     result = (jlong) (now.tv_sec*1000000000LL + now.tv_nsec);
540 #else
541     result = (jlong) -1;
542 #endif
543 
544     RETURN_LONG(result);
545 }
546 
547 /*
548  * static void dumpHprofData(String fileName)
549  *
550  * Cause "hprof" data to be dumped.  We can throw an IOException if an
551  * error occurs during file handling.
552  */
Dalvik_dalvik_system_VMDebug_dumpHprofData(const u4 * args,JValue * pResult)553 static void Dalvik_dalvik_system_VMDebug_dumpHprofData(const u4* args,
554     JValue* pResult)
555 {
556 #ifdef WITH_HPROF
557     StringObject* fileNameStr = (StringObject*) args[0];
558     char* fileName;
559     int result;
560 
561     if (fileNameStr == NULL) {
562         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
563         RETURN_VOID();
564     }
565 
566     fileName = dvmCreateCstrFromString(fileNameStr);
567     if (fileName == NULL) {
568         /* unexpected -- malloc failure? */
569         dvmThrowException("Ljava/lang/RuntimeException;", "malloc failure?");
570         RETURN_VOID();
571     }
572 
573     result = hprofDumpHeap(fileName);
574     free(fileName);
575 
576     if (result != 0) {
577         /* ideally we'd throw something more specific based on actual failure */
578         dvmThrowException("Ljava/lang/RuntimeException;",
579             "Failure during heap dump -- check log output for details");
580         RETURN_VOID();
581     }
582 #else
583     dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
584 #endif
585 
586     RETURN_VOID();
587 }
588 
589 const DalvikNativeMethod dvm_dalvik_system_VMDebug[] = {
590     { "getAllocCount",              "(I)I",
591         Dalvik_dalvik_system_VMDebug_getAllocCount },
592     { "resetAllocCount",            "(I)V",
593         Dalvik_dalvik_system_VMDebug_resetAllocCount },
594     //{ "print",              "(Ljava/lang/String;)V",
595     //    Dalvik_dalvik_system_VMDebug_print },
596     { "startAllocCounting",         "()V",
597         Dalvik_dalvik_system_VMDebug_startAllocCounting },
598     { "stopAllocCounting",          "()V",
599         Dalvik_dalvik_system_VMDebug_stopAllocCounting },
600     { "startMethodTracing",         "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V",
601         Dalvik_dalvik_system_VMDebug_startMethodTracing },
602     { "isMethodTracingActive",      "()Z",
603         Dalvik_dalvik_system_VMDebug_isMethodTracingActive },
604     { "stopMethodTracing",          "()V",
605         Dalvik_dalvik_system_VMDebug_stopMethodTracing },
606     { "startEmulatorTracing",       "()V",
607         Dalvik_dalvik_system_VMDebug_startEmulatorTracing },
608     { "stopEmulatorTracing",        "()V",
609         Dalvik_dalvik_system_VMDebug_stopEmulatorTracing },
610     { "setAllocationLimit",         "(I)I",
611         Dalvik_dalvik_system_VMDebug_setAllocationLimit },
612     { "setGlobalAllocationLimit",   "(I)I",
613         Dalvik_dalvik_system_VMDebug_setGlobalAllocationLimit },
614     { "startInstructionCounting",   "()V",
615         Dalvik_dalvik_system_VMDebug_startInstructionCounting },
616     { "stopInstructionCounting",    "()V",
617         Dalvik_dalvik_system_VMDebug_stopInstructionCounting },
618     { "resetInstructionCount",      "()V",
619         Dalvik_dalvik_system_VMDebug_resetInstructionCount },
620     { "getInstructionCount",        "([I)V",
621         Dalvik_dalvik_system_VMDebug_getInstructionCount },
622     { "isDebuggerConnected",        "()Z",
623         Dalvik_dalvik_system_VMDebug_isDebuggerConnected },
624     { "isDebuggingEnabled",         "()Z",
625         Dalvik_dalvik_system_VMDebug_isDebuggingEnabled },
626     { "lastDebuggerActivity",       "()J",
627         Dalvik_dalvik_system_VMDebug_lastDebuggerActivity },
628     { "printLoadedClasses",         "(I)V",
629         Dalvik_dalvik_system_VMDebug_printLoadedClasses },
630     { "getLoadedClassCount",        "()I",
631         Dalvik_dalvik_system_VMDebug_getLoadedClassCount },
632     { "threadCpuTimeNanos",         "()J",
633         Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos },
634     { "dumpHprofData",              "(Ljava/lang/String;)V",
635         Dalvik_dalvik_system_VMDebug_dumpHprofData },
636     { NULL, NULL, NULL },
637 };
638 
639