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