dalvik_system_VMDebug.cc revision 7e7e0f47628fb358da70c5e2766545c4f0596235
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 17277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#include "dalvik_system_VMDebug.h" 18277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe 19eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include <string.h> 20eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include <unistd.h> 21eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes 229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "class_linker.h" 2362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 24872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "debugger.h" 257410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier#include "gc/space/bump_pointer_space.h" 2609b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/dlmalloc_space.h" 2709b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/large_object_space.h" 2809b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/space-inl.h" 291f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier#include "gc/space/zygote_space.h" 301121e0b619d0c9df36c57396b2234a9d570b4923Jesse Wilson#include "hprof/hprof.h" 31eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h" 322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class.h" 33dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers#include "ScopedLocalRef.h" 349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "ScopedUtfChars.h" 3553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#include "scoped_fast_native_object_access.h" 36eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "trace.h" 37dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers#include "well_known_classes.h" 389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesnamespace art { 409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 410512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) { 42dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers static const char* features[] = { 43dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "method-trace-profiling", 44dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "method-trace-profiling-streaming", 45dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "method-sample-profiling", 46dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "hprof-heap-dump", 47dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "hprof-heap-dump-streaming", 48dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers }; 49dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers jobjectArray result = env->NewObjectArray(arraysize(features), 50dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers WellKnownClasses::java_lang_String, 51dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers nullptr); 52dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers if (result != nullptr) { 53dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers for (size_t i = 0; i < arraysize(features); ++i) { 54dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers ScopedLocalRef<jstring> jfeature(env, env->NewStringUTF(features[i])); 55dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers if (jfeature.get() == nullptr) { 56dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers return nullptr; 57dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers } 58dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers env->SetObjectArrayElement(result, i, jfeature.get()); 59dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers } 60dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers } 61dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers return result; 629d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 639d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 640512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_startAllocCounting(JNIEnv*, jclass) { 659ef78b59da51080882e47505896b420977fd79aeMathieu Chartier Runtime::Current()->SetStatsEnabled(true); 669d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 679d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 680512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopAllocCounting(JNIEnv*, jclass) { 699ef78b59da51080882e47505896b420977fd79aeMathieu Chartier Runtime::Current()->SetStatsEnabled(false); 709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 719d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 721bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesstatic jint VMDebug_getAllocCount(JNIEnv*, jclass, jint kind) { 739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetStat(kind); 749d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 759d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 760512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) { 779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Runtime::Current()->ResetStats(kinds); 789d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 799d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 8023009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Haostatic void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags, 8123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao jboolean samplingEnabled, jint intervalUs) { 827e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe Trace::Start("[DDMS]", -1, bufferSize, flags, Trace::TraceOutputMode::kDDMS, 837e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, 847e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe intervalUs); 859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 869d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 8700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, 884044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jobject javaFd, jint bufferSize, jint flags, 894044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jboolean samplingEnabled, jint intervalUs) { 909d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int originalFd = jniGetFDFromFileDescriptor(env, javaFd); 919d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (originalFd < 0) { 929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 949d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 959d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int fd = dup(originalFd); 969d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (fd < 0) { 9700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 980aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray soa.Self()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", 9962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "dup(%d) failed: %s", originalFd, strerror(errno)); 1009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1019d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1029d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars traceFilename(env, javaTraceFilename); 1049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (traceFilename.c_str() == NULL) { 1059d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1077e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, Trace::TraceOutputMode::kFile, 1087e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, 1097e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe intervalUs); 1109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 11200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename, 1134044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jint bufferSize, jint flags, 1144044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jboolean samplingEnabled, jint intervalUs) { 1159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars traceFilename(env, javaTraceFilename); 1169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (traceFilename.c_str() == NULL) { 1179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1197e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, Trace::TraceOutputMode::kFile, 1207e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, 1217e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe intervalUs); 1229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 12464caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haostatic jint VMDebug_getMethodTracingMode(JNIEnv*, jclass) { 12564caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao return Trace::GetMethodTracingMode(); 1269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1279d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1280512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopMethodTracing(JNIEnv*, jclass) { 129e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Trace::Stop(); 1309d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1320512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_startEmulatorTracing(JNIEnv*, jclass) { 1339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes UNIMPLEMENTED(WARNING); 1347934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // dvmEmulatorTraceStart(); 1359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1370512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopEmulatorTracing(JNIEnv*, jclass) { 1389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes UNIMPLEMENTED(WARNING); 1397934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // dvmEmulatorTraceStop(); 1409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1419d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1420512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) { 143c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsDebuggerActive(); 1449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1459d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1460512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) { 147c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsJdwpConfigured(); 1489d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1499d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1500512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) { 151872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return Dbg::LastDebuggerActivity(); 1529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1539d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 15462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void ThrowUnsupportedOperationException(JNIEnv* env) { 15500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1560aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray soa.Self()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", NULL); 15762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 15862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 15962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void VMDebug_startInstructionCounting(JNIEnv* env, jclass) { 16062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1619d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1629d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 16300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_stopInstructionCounting(JNIEnv* env, jclass) { 16462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1659d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1669d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 16700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_getInstructionCount(JNIEnv* env, jclass, jintArray /*javaCounts*/) { 16862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 17100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_resetInstructionCount(JNIEnv* env, jclass) { 17262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1749d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_printLoadedClasses(JNIEnv* env, jclass, jint flags) { 17653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedFastNativeObjectAccess soa(env); 1779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetClassLinker()->DumpAllClasses(flags); 1789d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1799d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1807dfb28c066159e6cde8181720f0c451a700ef966Ian Rogersstatic jint VMDebug_getLoadedClassCount(JNIEnv* env, jclass) { 18153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedFastNativeObjectAccess soa(env); 1829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetClassLinker()->NumLoadedClasses(); 1839d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 1869d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Returns the thread-specific CPU-time clock value for the current thread, 1879d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * or -1 if the feature isn't supported. 1889d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 1890512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) { 1900512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes return ThreadCpuNanoTime(); 1919d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 1949d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * static void dumpHprofData(String fileName, FileDescriptor fd) 1959d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * 1969d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Cause "hprof" data to be dumped. We can throw an IOException if an 1979d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * error occurs during file handling. 1989d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 1990512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jobject javaFd) { 2009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // Only one of these may be NULL. 2019d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (javaFilename == NULL && javaFd == NULL) { 20200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2030aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNullPointerException("fileName == null && fd == null"); 2049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 2059d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes std::string filename; 2089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (javaFilename != NULL) { 2099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars chars(env, javaFilename); 2109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (env->ExceptionCheck()) { 2119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 2129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes filename = chars.c_str(); 2149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } else { 2159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes filename = "[fd]"; 2169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int fd = -1; 2199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (javaFd != NULL) { 2209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes fd = jniGetFDFromFileDescriptor(env, javaFd); 2219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (fd < 0) { 22200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 22362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowRuntimeException("Invalid file descriptor"); 2249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 2259d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2279d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 228622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof::DumpHeap(filename.c_str(), fd, false); 2299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2309d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 231eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughesstatic void VMDebug_dumpHprofDataDdms(JNIEnv*, jclass) { 232622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof::DumpHeap("[DDMS]", -1, true); 2339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2350512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_dumpReferenceTables(JNIEnv* env, jclass) { 23600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "--- reference table dump ---"; 2389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 23900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->DumpReferenceTables(LOG(INFO)); 24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Vm()->DumpReferenceTables(LOG(INFO)); 2419d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "---"; 2439d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2450512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_crash(JNIEnv*, jclass) { 24681ff3184e7eb8de4605c7646674ea4f9fa29b5f3Elliott Hughes LOG(FATAL) << "Crashing runtime on request"; 2479d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2489d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2490512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_infopoint(JNIEnv*, jclass, jint id) { 2509d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "VMDebug infopoint " << id << " hit"; 2519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 25300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass, 25400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jboolean countAssignable) { 25500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 256412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier gc::Heap* heap = Runtime::Current()->GetHeap(); 25783c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier // We only want reachable instances, so do a GC. Heap::VisitObjects visits all of the heap 25883c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier // objects in the all spaces and the allocation stack. 259412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier heap->CollectGarbage(false); 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = soa.Decode<mirror::Class*>(javaClass); 261412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier if (c == nullptr) { 2629d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return 0; 2639d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::vector<mirror::Class*> classes; 265ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes classes.push_back(c); 266ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes uint64_t count = 0; 267412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier heap->CountInstances(classes, countAssignable, &count); 268ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes return count; 2699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 27109b07a96094086e205948717666025909a75163bHiroshi Yamauchi// We export the VM internal per-heap-space size/alloc/free metrics 27209b07a96094086e205948717666025909a75163bHiroshi Yamauchi// for the zygote space, alloc space (application heap), and the large 27309b07a96094086e205948717666025909a75163bHiroshi Yamauchi// object space for dumpsys meminfo. The other memory region data such 27409b07a96094086e205948717666025909a75163bHiroshi Yamauchi// as PSS, private/shared dirty/shared data are available via 27509b07a96094086e205948717666025909a75163bHiroshi Yamauchi// /proc/<pid>/smaps. 27609b07a96094086e205948717666025909a75163bHiroshi Yamauchistatic void VMDebug_getHeapSpaceStats(JNIEnv* env, jclass, jlongArray data) { 2776b99dd10d8a4869bbf7e9263a350185e5ebe32e4Ian Rogers jlong* arr = reinterpret_cast<jlong*>(env->GetPrimitiveArrayCritical(data, 0)); 2787410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier if (arr == nullptr || env->GetArrayLength(data) < 9) { 27909b07a96094086e205948717666025909a75163bHiroshi Yamauchi return; 28009b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 28109b07a96094086e205948717666025909a75163bHiroshi Yamauchi 28209b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocSize = 0; 28309b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocUsed = 0; 28409b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteSize = 0; 28509b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteUsed = 0; 28609b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsSize = 0; 28709b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsUsed = 0; 28809b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 2897410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier for (gc::space::ContinuousSpace* space : heap->GetContinuousSpaces()) { 29009b07a96094086e205948717666025909a75163bHiroshi Yamauchi if (space->IsImageSpace()) { 29109b07a96094086e205948717666025909a75163bHiroshi Yamauchi // Currently don't include the image space. 29209b07a96094086e205948717666025909a75163bHiroshi Yamauchi } else if (space->IsZygoteSpace()) { 2931f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier gc::space::ZygoteSpace* zygote_space = space->AsZygoteSpace(); 2941f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier zygoteSize += zygote_space->Size(); 2951f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier zygoteUsed += zygote_space->GetBytesAllocated(); 2967410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier } else if (space->IsMallocSpace()) { 2977410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier // This is a malloc space. 298cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi gc::space::MallocSpace* malloc_space = space->AsMallocSpace(); 299cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi allocSize += malloc_space->GetFootprint(); 300cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi allocUsed += malloc_space->GetBytesAllocated(); 3017410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier } else if (space->IsBumpPointerSpace()) { 302692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier ScopedObjectAccess soa(env); 3037410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier gc::space::BumpPointerSpace* bump_pointer_space = space->AsBumpPointerSpace(); 3047410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier allocSize += bump_pointer_space->Size(); 3057410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier allocUsed += bump_pointer_space->GetBytesAllocated(); 30609b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 30709b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 3087410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier for (gc::space::DiscontinuousSpace* space : heap->GetDiscontinuousSpaces()) { 30909b07a96094086e205948717666025909a75163bHiroshi Yamauchi if (space->IsLargeObjectSpace()) { 31009b07a96094086e205948717666025909a75163bHiroshi Yamauchi largeObjectsSize += space->AsLargeObjectSpace()->GetBytesAllocated(); 31109b07a96094086e205948717666025909a75163bHiroshi Yamauchi largeObjectsUsed += largeObjectsSize; 31209b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 31309b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 31409b07a96094086e205948717666025909a75163bHiroshi Yamauchi 31509b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocFree = allocSize - allocUsed; 31609b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteFree = zygoteSize - zygoteUsed; 31709b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsFree = largeObjectsSize - largeObjectsUsed; 31809b07a96094086e205948717666025909a75163bHiroshi Yamauchi 31909b07a96094086e205948717666025909a75163bHiroshi Yamauchi int j = 0; 32009b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocSize; 32109b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocUsed; 32209b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocFree; 32309b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteSize; 32409b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteUsed; 32509b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteFree; 32609b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsSize; 32709b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsUsed; 32809b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsFree; 32909b07a96094086e205948717666025909a75163bHiroshi Yamauchi env->ReleasePrimitiveArrayCritical(data, arr, 0); 33009b07a96094086e205948717666025909a75163bHiroshi Yamauchi} 33109b07a96094086e205948717666025909a75163bHiroshi Yamauchi 3320512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JNINativeMethod gMethods[] = { 3339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"), 3349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, crash, "()V"), 3359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;Ljava/io/FileDescriptor;)V"), 3369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"), 3379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"), 3389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"), 33909b07a96094086e205948717666025909a75163bHiroshi Yamauchi NATIVE_METHOD(VMDebug, getHeapSpaceStats, "([J)V"), 3409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"), 34153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMDebug, getLoadedClassCount, "!()I"), 3429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"), 3439d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, infopoint, "(I)V"), 34453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMDebug, isDebuggerConnected, "!()Z"), 34553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMDebug, isDebuggingEnabled, "!()Z"), 34664caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao NATIVE_METHOD(VMDebug, getMethodTracingMode, "()I"), 34753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMDebug, lastDebuggerActivity, "!()J"), 34853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMDebug, printLoadedClasses, "!(I)V"), 3499d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, resetAllocCount, "(I)V"), 3509d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, resetInstructionCount, "()V"), 3519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startAllocCounting, "()V"), 3529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"), 3539d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"), 35423009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(IIZI)V"), 3554044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;Ljava/io/FileDescriptor;IIZI)V"), 3564044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;IIZI)V"), 3579d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"), 3589d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopEmulatorTracing, "()V"), 3599d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopInstructionCounting, "()V"), 3609d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopMethodTracing, "()V"), 36153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMDebug, threadCpuTimeNanos, "!()J"), 3629d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes}; 3639d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 3649d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid register_dalvik_system_VMDebug(JNIEnv* env) { 365eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("dalvik/system/VMDebug"); 3669d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 3679d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 3689d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} // namespace art 369