dalvik_system_VMDebug.cc revision 09b07a96094086e205948717666025909a75163b
19d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 29d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Copyright (C) 2008 The Android Open Source Project 39d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * 49d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 59d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * you may not use this file except in compliance with the License. 69d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * You may obtain a copy of the License at 79d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * 89d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 99d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * 109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Unless required by applicable law or agreed to in writing, software 119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * See the License for the specific language governing permissions and 149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * limitations under the License. 159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 17eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include <string.h> 18eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include <unistd.h> 19eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes 209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "class_linker.h" 2162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 22872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "debugger.h" 2309b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/dlmalloc_space.h" 2409b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/large_object_space.h" 2509b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/space-inl.h" 261121e0b619d0c9df36c57396b2234a9d570b4923Jesse Wilson#include "hprof/hprof.h" 27eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h" 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class.h" 299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "ScopedUtfChars.h" 3000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "toStringArray.h" 32eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "trace.h" 339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesnamespace art { 359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 360512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) { 379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes std::vector<std::string> features; 38e343b76af81a005ef64f5e75a555389fd9147dabjeffhao features.push_back("method-trace-profiling"); 39e343b76af81a005ef64f5e75a555389fd9147dabjeffhao features.push_back("method-trace-profiling-streaming"); 40767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes features.push_back("hprof-heap-dump"); 41767a147529da3ee8240f3ce4cd3af22ae454be64Elliott Hughes features.push_back("hprof-heap-dump-streaming"); 429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return toStringArray(env, features); 439d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 450512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_startAllocCounting(JNIEnv*, jclass) { 469d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Runtime::Current()->SetStatsEnabled(true); 479d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 489d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 490512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopAllocCounting(JNIEnv*, jclass) { 509d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Runtime::Current()->SetStatsEnabled(false); 519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 531bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesstatic jint VMDebug_getAllocCount(JNIEnv*, jclass, jint kind) { 549d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetStat(kind); 559d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 569d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 570512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) { 589d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Runtime::Current()->ResetStats(kinds); 599d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 609d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 611bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesstatic void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags) { 62e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Trace::Start("[DDMS]", -1, bufferSize, flags, true); 639d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 649d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 6500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, 6600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject javaFd, jint bufferSize, jint flags) { 679d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int originalFd = jniGetFDFromFileDescriptor(env, javaFd); 689d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (originalFd < 0) { 699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 719d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 729d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int fd = dup(originalFd); 739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (fd < 0) { 7400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/RuntimeException;", 7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "dup(%d) failed: %s", originalFd, strerror(errno)); 789d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 799d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 809d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 819d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars traceFilename(env, javaTraceFilename); 829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (traceFilename.c_str() == NULL) { 839d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 85e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, false); 869d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 879d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 8800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename, 8900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jint bufferSize, jint flags) { 909d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars traceFilename(env, javaTraceFilename); 919d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (traceFilename.c_str() == NULL) { 929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 94e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, false); 959d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 969d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 970512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isMethodTracingActive(JNIEnv*, jclass) { 9862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return Trace::IsMethodTracingActive(); 999d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1010512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopMethodTracing(JNIEnv*, jclass) { 102e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Trace::Stop(); 1039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1050512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_startEmulatorTracing(JNIEnv*, jclass) { 1069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes UNIMPLEMENTED(WARNING); 1079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes //dvmEmulatorTraceStart(); 1089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1100512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopEmulatorTracing(JNIEnv*, jclass) { 1119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes UNIMPLEMENTED(WARNING); 1129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes //dvmEmulatorTraceStop(); 1139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1150512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) { 116c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsDebuggerActive(); 1179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1190512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) { 120c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsJdwpConfigured(); 1219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1230512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) { 124872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return Dbg::LastDebuggerActivity(); 1259d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 12762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void ThrowUnsupportedOperationException(JNIEnv* env) { 12800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 12962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 13062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewException(throw_location, "Ljava/lang/UnsupportedOperationException;", NULL); 13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 13362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void VMDebug_startInstructionCounting(JNIEnv* env, jclass) { 13462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 13700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_stopInstructionCounting(JNIEnv* env, jclass) { 13862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 14100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_getInstructionCount(JNIEnv* env, jclass, jintArray /*javaCounts*/) { 14262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1439d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 14500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_resetInstructionCount(JNIEnv* env, jclass) { 14662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1479d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1489d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 14900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_printLoadedClasses(JNIEnv* env, jclass, jint flags) { 15000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetClassLinker()->DumpAllClasses(flags); 1529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1539d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1540512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jint VMDebug_getLoadedClassCount(JNIEnv*, jclass) { 1559d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetClassLinker()->NumLoadedClasses(); 1569d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1579d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1589d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 1599d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Returns the thread-specific CPU-time clock value for the current thread, 1609d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * or -1 if the feature isn't supported. 1619d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 1620512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) { 1630512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes return ThreadCpuNanoTime(); 1649d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1659d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1669d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 1679d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * static void dumpHprofData(String fileName, FileDescriptor fd) 1689d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * 1699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Cause "hprof" data to be dumped. We can throw an IOException if an 1709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * error occurs during file handling. 1719d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 1720512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jobject javaFd) { 1739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // Only one of these may be NULL. 1749d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (javaFilename == NULL && javaFd == NULL) { 17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 17662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowNullPointerException(NULL, "fileName == null && fd == null"); 1779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1789d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1799d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1809d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes std::string filename; 1819d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (javaFilename != NULL) { 1829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars chars(env, javaFilename); 1839d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (env->ExceptionCheck()) { 1849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1869d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes filename = chars.c_str(); 1879d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } else { 1889d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes filename = "[fd]"; 1899d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1909d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1919d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int fd = -1; 1929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (javaFd != NULL) { 1939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes fd = jniGetFDFromFileDescriptor(env, javaFd); 1949d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (fd < 0) { 19500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 19662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowRuntimeException("Invalid file descriptor"); 1979d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1989d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1999d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 201622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof::DumpHeap(filename.c_str(), fd, false); 2029d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 204eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughesstatic void VMDebug_dumpHprofDataDdms(JNIEnv*, jclass) { 205622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof::DumpHeap("[DDMS]", -1, true); 2069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2080512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_dumpReferenceTables(JNIEnv* env, jclass) { 20900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "--- reference table dump ---"; 2119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 21200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->DumpReferenceTables(LOG(INFO)); 21300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Vm()->DumpReferenceTables(LOG(INFO)); 2149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "---"; 2169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2180512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_crash(JNIEnv*, jclass) { 21981ff3184e7eb8de4605c7646674ea4f9fa29b5f3Elliott Hughes LOG(FATAL) << "Crashing runtime on request"; 2209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2220512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_infopoint(JNIEnv*, jclass, jint id) { 2239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "VMDebug infopoint " << id << " hit"; 2249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2259d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 22600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass, 22700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jboolean countAssignable) { 22800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = soa.Decode<mirror::Class*>(javaClass); 2309d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (c == NULL) { 2319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return 0; 2329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::vector<mirror::Class*> classes; 234ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes classes.push_back(c); 235ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes uint64_t count = 0; 236ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes Runtime::Current()->GetHeap()->CountInstances(classes, countAssignable, &count); 237ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes return count; 2389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 24009b07a96094086e205948717666025909a75163bHiroshi Yamauchi// We export the VM internal per-heap-space size/alloc/free metrics 24109b07a96094086e205948717666025909a75163bHiroshi Yamauchi// for the zygote space, alloc space (application heap), and the large 24209b07a96094086e205948717666025909a75163bHiroshi Yamauchi// object space for dumpsys meminfo. The other memory region data such 24309b07a96094086e205948717666025909a75163bHiroshi Yamauchi// as PSS, private/shared dirty/shared data are available via 24409b07a96094086e205948717666025909a75163bHiroshi Yamauchi// /proc/<pid>/smaps. 24509b07a96094086e205948717666025909a75163bHiroshi Yamauchistatic void VMDebug_getHeapSpaceStats(JNIEnv* env, jclass, jlongArray data) { 24609b07a96094086e205948717666025909a75163bHiroshi Yamauchi jlong* arr = (jlong*) env->GetPrimitiveArrayCritical(data, 0); 24709b07a96094086e205948717666025909a75163bHiroshi Yamauchi if (arr == NULL || env->GetArrayLength(data) < 9) { 24809b07a96094086e205948717666025909a75163bHiroshi Yamauchi return; 24909b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 25009b07a96094086e205948717666025909a75163bHiroshi Yamauchi 25109b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocSize = 0; 25209b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocUsed = 0; 25309b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteSize = 0; 25409b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteUsed = 0; 25509b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsSize = 0; 25609b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsUsed = 0; 25709b07a96094086e205948717666025909a75163bHiroshi Yamauchi 25809b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 25909b07a96094086e205948717666025909a75163bHiroshi Yamauchi const std::vector<gc::space::ContinuousSpace*>& continuous_spaces = heap->GetContinuousSpaces(); 26009b07a96094086e205948717666025909a75163bHiroshi Yamauchi const std::vector<gc::space::DiscontinuousSpace*>& discontinuous_spaces = heap->GetDiscontinuousSpaces(); 26109b07a96094086e205948717666025909a75163bHiroshi Yamauchi typedef std::vector<gc::space::ContinuousSpace*>::const_iterator It; 26209b07a96094086e205948717666025909a75163bHiroshi Yamauchi for (It it = continuous_spaces.begin(), end = continuous_spaces.end(); it != end; ++it) { 26309b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::space::ContinuousSpace* space = *it; 26409b07a96094086e205948717666025909a75163bHiroshi Yamauchi if (space->IsImageSpace()) { 26509b07a96094086e205948717666025909a75163bHiroshi Yamauchi // Currently don't include the image space. 26609b07a96094086e205948717666025909a75163bHiroshi Yamauchi } else if (space->IsZygoteSpace()) { 26709b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::space::DlMallocSpace* dlmalloc_space = space->AsDlMallocSpace(); 26809b07a96094086e205948717666025909a75163bHiroshi Yamauchi zygoteSize += dlmalloc_space->GetFootprint(); 26909b07a96094086e205948717666025909a75163bHiroshi Yamauchi zygoteUsed += dlmalloc_space->GetBytesAllocated(); 27009b07a96094086e205948717666025909a75163bHiroshi Yamauchi } else { 27109b07a96094086e205948717666025909a75163bHiroshi Yamauchi // This is the alloc space. 27209b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::space::DlMallocSpace* dlmalloc_space = space->AsDlMallocSpace(); 27309b07a96094086e205948717666025909a75163bHiroshi Yamauchi allocSize += dlmalloc_space->GetFootprint(); 27409b07a96094086e205948717666025909a75163bHiroshi Yamauchi allocUsed += dlmalloc_space->GetBytesAllocated(); 27509b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 27609b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 27709b07a96094086e205948717666025909a75163bHiroshi Yamauchi typedef std::vector<gc::space::DiscontinuousSpace*>::const_iterator It2; 27809b07a96094086e205948717666025909a75163bHiroshi Yamauchi for (It2 it = discontinuous_spaces.begin(), end = discontinuous_spaces.end(); it != end; ++it) { 27909b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::space::DiscontinuousSpace* space = *it; 28009b07a96094086e205948717666025909a75163bHiroshi Yamauchi if (space->IsLargeObjectSpace()) { 28109b07a96094086e205948717666025909a75163bHiroshi Yamauchi largeObjectsSize += space->AsLargeObjectSpace()->GetBytesAllocated(); 28209b07a96094086e205948717666025909a75163bHiroshi Yamauchi largeObjectsUsed += largeObjectsSize; 28309b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 28409b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 28509b07a96094086e205948717666025909a75163bHiroshi Yamauchi 28609b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocFree = allocSize - allocUsed; 28709b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteFree = zygoteSize - zygoteUsed; 28809b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsFree = largeObjectsSize - largeObjectsUsed; 28909b07a96094086e205948717666025909a75163bHiroshi Yamauchi 29009b07a96094086e205948717666025909a75163bHiroshi Yamauchi int j = 0; 29109b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocSize; 29209b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocUsed; 29309b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocFree; 29409b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteSize; 29509b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteUsed; 29609b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteFree; 29709b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsSize; 29809b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsUsed; 29909b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsFree; 30009b07a96094086e205948717666025909a75163bHiroshi Yamauchi env->ReleasePrimitiveArrayCritical(data, arr, 0); 30109b07a96094086e205948717666025909a75163bHiroshi Yamauchi} 30209b07a96094086e205948717666025909a75163bHiroshi Yamauchi 3030512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JNINativeMethod gMethods[] = { 3049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"), 3059d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, crash, "()V"), 3069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;Ljava/io/FileDescriptor;)V"), 3079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"), 3089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"), 3099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"), 31009b07a96094086e205948717666025909a75163bHiroshi Yamauchi NATIVE_METHOD(VMDebug, getHeapSpaceStats, "([J)V"), 3119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"), 3129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"), 3139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"), 3149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, infopoint, "(I)V"), 3159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, isDebuggerConnected, "()Z"), 3169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, isDebuggingEnabled, "()Z"), 3179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, isMethodTracingActive, "()Z"), 3189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, lastDebuggerActivity, "()J"), 3199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, printLoadedClasses, "(I)V"), 3209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, resetAllocCount, "(I)V"), 3219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, resetInstructionCount, "()V"), 3229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startAllocCounting, "()V"), 3239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"), 3249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"), 3259d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(II)V"), 3269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V"), 3279d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;II)V"), 3289d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"), 3299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopEmulatorTracing, "()V"), 3309d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopInstructionCounting, "()V"), 3319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopMethodTracing, "()V"), 3329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, threadCpuTimeNanos, "()J"), 3339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes}; 3349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 3359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid register_dalvik_system_VMDebug(JNIEnv* env) { 336eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("dalvik/system/VMDebug"); 3379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 3389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 3399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} // namespace art 340