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 22a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi#include <sstream> 23a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 24a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi#include "base/histogram-inl.h" 2580afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/time_utils.h" 269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "class_linker.h" 2762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 28872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "debugger.h" 297410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier#include "gc/space/bump_pointer_space.h" 3009b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/dlmalloc_space.h" 3109b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/large_object_space.h" 3209b07a96094086e205948717666025909a75163bHiroshi Yamauchi#include "gc/space/space-inl.h" 331f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier#include "gc/space/zygote_space.h" 34c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "handle_scope-inl.h" 351121e0b619d0c9df36c57396b2234a9d570b4923Jesse Wilson#include "hprof/hprof.h" 36c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "java_vm_ext.h" 37eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "jni_internal.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class.h" 39c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "mirror/object_array-inl.h" 40dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers#include "ScopedLocalRef.h" 419d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes#include "ScopedUtfChars.h" 420795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_fast_native_object_access-inl.h" 43eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "trace.h" 44dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers#include "well_known_classes.h" 459d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 469d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesnamespace art { 479d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 480512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) { 49dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers static const char* features[] = { 50dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "method-trace-profiling", 51dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "method-trace-profiling-streaming", 52dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "method-sample-profiling", 53dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "hprof-heap-dump", 54dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers "hprof-heap-dump-streaming", 55dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers }; 56dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers jobjectArray result = env->NewObjectArray(arraysize(features), 57dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers WellKnownClasses::java_lang_String, 58dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers nullptr); 59dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers if (result != nullptr) { 60dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers for (size_t i = 0; i < arraysize(features); ++i) { 61dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers ScopedLocalRef<jstring> jfeature(env, env->NewStringUTF(features[i])); 62dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers if (jfeature.get() == nullptr) { 63dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers return nullptr; 64dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers } 65dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers env->SetObjectArrayElement(result, i, jfeature.get()); 66dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers } 67dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers } 68dd157d732b557a854b3689faf8a24170fb47c270Ian Rogers return result; 699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 709d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 710512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_startAllocCounting(JNIEnv*, jclass) { 729ef78b59da51080882e47505896b420977fd79aeMathieu Chartier Runtime::Current()->SetStatsEnabled(true); 739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 749d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 750512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopAllocCounting(JNIEnv*, jclass) { 769ef78b59da51080882e47505896b420977fd79aeMathieu Chartier Runtime::Current()->SetStatsEnabled(false); 779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 789d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 791bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesstatic jint VMDebug_getAllocCount(JNIEnv*, jclass, jint kind) { 809d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetStat(kind); 819d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 830512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) { 849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Runtime::Current()->ResetStats(kinds); 859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 869d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 8723009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Haostatic void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags, 8823009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao jboolean samplingEnabled, jint intervalUs) { 897e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe Trace::Start("[DDMS]", -1, bufferSize, flags, Trace::TraceOutputMode::kDDMS, 907e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, 917e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe intervalUs); 929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 9400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, 954044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jobject javaFd, jint bufferSize, jint flags, 96ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou jboolean samplingEnabled, jint intervalUs, 97ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou jboolean streamingOutput) { 989d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int originalFd = jniGetFDFromFileDescriptor(env, javaFd); 999d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (originalFd < 0) { 1009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1019d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1029d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int fd = dup(originalFd); 1049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (fd < 0) { 10500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1060aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray soa.Self()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", 10762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "dup(%d) failed: %s", originalFd, strerror(errno)); 1089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars traceFilename(env, javaTraceFilename); 1122cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (traceFilename.c_str() == nullptr) { 1139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 115ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou Trace::TraceOutputMode outputMode = streamingOutput 116ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou ? Trace::TraceOutputMode::kStreaming 117ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou : Trace::TraceOutputMode::kFile; 118ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, outputMode, 1197e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, 1207e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe intervalUs); 1219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 12300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename, 1244044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jint bufferSize, jint flags, 1254044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao jboolean samplingEnabled, jint intervalUs) { 1269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars traceFilename(env, javaTraceFilename); 1272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (traceFilename.c_str() == nullptr) { 1289d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 1299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 1307e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, Trace::TraceOutputMode::kFile, 1317e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing, 1327e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe intervalUs); 1339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 13564caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haostatic jint VMDebug_getMethodTracingMode(JNIEnv*, jclass) { 13664caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao return Trace::GetMethodTracingMode(); 1379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1390512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopMethodTracing(JNIEnv*, jclass) { 140e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Trace::Stop(); 1419d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1430512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_startEmulatorTracing(JNIEnv*, jclass) { 1449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes UNIMPLEMENTED(WARNING); 1457934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // dvmEmulatorTraceStart(); 1469d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1479d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1480512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_stopEmulatorTracing(JNIEnv*, jclass) { 1499d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes UNIMPLEMENTED(WARNING); 1507934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // dvmEmulatorTraceStop(); 1519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1530512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) { 154c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsDebuggerActive(); 1559d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1569d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1570512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) { 158c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsJdwpConfigured(); 1599d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1609d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 1610512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) { 162872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return Dbg::LastDebuggerActivity(); 1639d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1649d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 16562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void ThrowUnsupportedOperationException(JNIEnv* env) { 16600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1672cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.Self()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", nullptr); 16862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} 16962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 17062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstatic void VMDebug_startInstructionCounting(JNIEnv* env, jclass) { 17162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1729d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 17400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_stopInstructionCounting(JNIEnv* env, jclass) { 17562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1769d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 17800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_getInstructionCount(JNIEnv* env, jclass, jintArray /*javaCounts*/) { 17962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1809d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1819d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 18200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_resetInstructionCount(JNIEnv* env, jclass) { 18362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowUnsupportedOperationException(env); 1849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 1859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 18600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void VMDebug_printLoadedClasses(JNIEnv* env, jclass, jint flags) { 187cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe class DumpClassVisitor : public ClassVisitor { 188cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe public: 189cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe explicit DumpClassVisitor(int dump_flags) : flags_(dump_flags) {} 190cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe 191cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe bool operator()(ObjPtr<mirror::Class> klass) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { 192cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe klass->DumpClass(LOG_STREAM(ERROR), flags_); 193cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe return true; 194cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe } 195cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe 196cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe private: 197cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe const int flags_; 198cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe }; 199cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe DumpClassVisitor visitor(flags); 200cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe 20153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedFastNativeObjectAccess soa(env); 202cc1b5357f83f0b787d51fbfde3fe870c8a2fa050Andreas Gampe return Runtime::Current()->GetClassLinker()->VisitClasses(&visitor); 2039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2057dfb28c066159e6cde8181720f0c451a700ef966Ian Rogersstatic jint VMDebug_getLoadedClassCount(JNIEnv* env, jclass) { 20653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ScopedFastNativeObjectAccess soa(env); 2079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return Runtime::Current()->GetClassLinker()->NumLoadedClasses(); 2089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 2119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Returns the thread-specific CPU-time clock value for the current thread, 2129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * or -1 if the feature isn't supported. 2139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 2140512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) { 2150512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughes return ThreadCpuNanoTime(); 2169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes/* 2199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * static void dumpHprofData(String fileName, FileDescriptor fd) 2209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * 2219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * Cause "hprof" data to be dumped. We can throw an IOException if an 2229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes * error occurs during file handling. 2239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes */ 2240512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jobject javaFd) { 2252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Only one of these may be null. 2262cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (javaFilename == nullptr && javaFd == nullptr) { 22700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2280aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNullPointerException("fileName == null && fd == null"); 2299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 2309d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes std::string filename; 2332cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (javaFilename != nullptr) { 2349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ScopedUtfChars chars(env, javaFilename); 2359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (env->ExceptionCheck()) { 2369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 2379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes filename = chars.c_str(); 2399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } else { 2409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes filename = "[fd]"; 2419d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2439d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes int fd = -1; 2442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (javaFd != nullptr) { 2459d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes fd = jniGetFDFromFileDescriptor(env, javaFd); 2469d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (fd < 0) { 24700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 24862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowRuntimeException("Invalid file descriptor"); 2499d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return; 2509d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 2529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 253622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof::DumpHeap(filename.c_str(), fd, false); 2549d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2559d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 256eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughesstatic void VMDebug_dumpHprofDataDdms(JNIEnv*, jclass) { 257622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof::DumpHeap("[DDMS]", -1, true); 2589d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2599d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2600512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_dumpReferenceTables(JNIEnv* env, jclass) { 26100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 2629d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "--- reference table dump ---"; 2639d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2643fec9ac0d5af1358d216eb2fdc2000ec0205f3f0Andreas Gampe soa.Env()->DumpReferenceTables(LOG_STREAM(INFO)); 2653fec9ac0d5af1358d216eb2fdc2000ec0205f3f0Andreas Gampe soa.Vm()->DumpReferenceTables(LOG_STREAM(INFO)); 2669d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2679d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "---"; 2689d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2700512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_crash(JNIEnv*, jclass) { 27181ff3184e7eb8de4605c7646674ea4f9fa29b5f3Elliott Hughes LOG(FATAL) << "Crashing runtime on request"; 2729d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2740512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMDebug_infopoint(JNIEnv*, jclass, jint id) { 2759d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes LOG(INFO) << "VMDebug infopoint " << id << " hit"; 2769d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2789d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartierstatic jlong VMDebug_countInstancesOfClass(JNIEnv* env, 2799d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier jclass, 2809d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier jclass javaClass, 28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jboolean countAssignable) { 28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 283f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier gc::Heap* const heap = Runtime::Current()->GetHeap(); 284f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier // Caller's responsibility to do GC if desired. 2850795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(javaClass); 286412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier if (c == nullptr) { 2879d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return 0; 2889d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 289e8a3c576301fd531d5f73a65fc8b84a63619d580Mathieu Chartier VariableSizedHandleScope hs(soa.Self()); 2909d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier std::vector<Handle<mirror::Class>> classes {hs.NewHandle(c)}; 291ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes uint64_t count = 0; 292412c7fced915fc8d4d5e4166e977d55c809168a6Mathieu Chartier heap->CountInstances(classes, countAssignable, &count); 293ec0f83d95e2174c97e93279ffa71642be7e12b60Elliott Hughes return count; 2949d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 2959d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 2969d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartierstatic jlongArray VMDebug_countInstancesOfClasses(JNIEnv* env, 2979d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier jclass, 2989d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier jobjectArray javaClasses, 299f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier jboolean countAssignable) { 300f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier ScopedObjectAccess soa(env); 301f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier gc::Heap* const heap = Runtime::Current()->GetHeap(); 302f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier // Caller's responsibility to do GC if desired. 3030795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier ObjPtr<mirror::ObjectArray<mirror::Class>> decoded_classes = 3040795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier soa.Decode<mirror::ObjectArray<mirror::Class>>(javaClasses); 305f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier if (decoded_classes == nullptr) { 306f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier return nullptr; 307f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 308e8a3c576301fd531d5f73a65fc8b84a63619d580Mathieu Chartier VariableSizedHandleScope hs(soa.Self()); 3099d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier std::vector<Handle<mirror::Class>> classes; 310f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier for (size_t i = 0, count = decoded_classes->GetLength(); i < count; ++i) { 3119d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier classes.push_back(hs.NewHandle(decoded_classes->Get(i))); 312f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 313f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier std::vector<uint64_t> counts(classes.size(), 0u); 314f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier // Heap::CountInstances can handle null and will put 0 for these classes. 315f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier heap->CountInstances(classes, countAssignable, &counts[0]); 3169d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier ObjPtr<mirror::LongArray> long_counts = mirror::LongArray::Alloc(soa.Self(), counts.size()); 317f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier if (long_counts == nullptr) { 318f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier soa.Self()->AssertPendingOOMException(); 319f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier return nullptr; 320f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 321f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier for (size_t i = 0; i < counts.size(); ++i) { 322f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier long_counts->Set(i, counts[i]); 323f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier } 324f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier return soa.AddLocalReference<jlongArray>(long_counts); 325f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier} 326f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier 32709b07a96094086e205948717666025909a75163bHiroshi Yamauchi// We export the VM internal per-heap-space size/alloc/free metrics 32809b07a96094086e205948717666025909a75163bHiroshi Yamauchi// for the zygote space, alloc space (application heap), and the large 32909b07a96094086e205948717666025909a75163bHiroshi Yamauchi// object space for dumpsys meminfo. The other memory region data such 33009b07a96094086e205948717666025909a75163bHiroshi Yamauchi// as PSS, private/shared dirty/shared data are available via 33109b07a96094086e205948717666025909a75163bHiroshi Yamauchi// /proc/<pid>/smaps. 33209b07a96094086e205948717666025909a75163bHiroshi Yamauchistatic void VMDebug_getHeapSpaceStats(JNIEnv* env, jclass, jlongArray data) { 3336b99dd10d8a4869bbf7e9263a350185e5ebe32e4Ian Rogers jlong* arr = reinterpret_cast<jlong*>(env->GetPrimitiveArrayCritical(data, 0)); 3347410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier if (arr == nullptr || env->GetArrayLength(data) < 9) { 33509b07a96094086e205948717666025909a75163bHiroshi Yamauchi return; 33609b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 33709b07a96094086e205948717666025909a75163bHiroshi Yamauchi 33809b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocSize = 0; 33909b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocUsed = 0; 34009b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteSize = 0; 34109b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteUsed = 0; 34209b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsSize = 0; 34309b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsUsed = 0; 34409b07a96094086e205948717666025909a75163bHiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 345a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier { 346a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ScopedObjectAccess soa(env); 347a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier for (gc::space::ContinuousSpace* space : heap->GetContinuousSpaces()) { 348a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier if (space->IsImageSpace()) { 349a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier // Currently don't include the image space. 350a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } else if (space->IsZygoteSpace()) { 351a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier gc::space::ZygoteSpace* zygote_space = space->AsZygoteSpace(); 352a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier zygoteSize += zygote_space->Size(); 353a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier zygoteUsed += zygote_space->GetBytesAllocated(); 354a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } else if (space->IsMallocSpace()) { 355a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier // This is a malloc space. 356a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier gc::space::MallocSpace* malloc_space = space->AsMallocSpace(); 357a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier allocSize += malloc_space->GetFootprint(); 358a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier allocUsed += malloc_space->GetBytesAllocated(); 359a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } else if (space->IsBumpPointerSpace()) { 360a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier gc::space::BumpPointerSpace* bump_pointer_space = space->AsBumpPointerSpace(); 361a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier allocSize += bump_pointer_space->Size(); 362a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier allocUsed += bump_pointer_space->GetBytesAllocated(); 363a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } 36409b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 365a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier for (gc::space::DiscontinuousSpace* space : heap->GetDiscontinuousSpaces()) { 366a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier if (space->IsLargeObjectSpace()) { 367a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier largeObjectsSize += space->AsLargeObjectSpace()->GetBytesAllocated(); 368a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier largeObjectsUsed += largeObjectsSize; 369a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } 37009b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 37109b07a96094086e205948717666025909a75163bHiroshi Yamauchi } 37209b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t allocFree = allocSize - allocUsed; 37309b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t zygoteFree = zygoteSize - zygoteUsed; 37409b07a96094086e205948717666025909a75163bHiroshi Yamauchi size_t largeObjectsFree = largeObjectsSize - largeObjectsUsed; 37509b07a96094086e205948717666025909a75163bHiroshi Yamauchi 37609b07a96094086e205948717666025909a75163bHiroshi Yamauchi int j = 0; 37709b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocSize; 37809b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocUsed; 37909b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = allocFree; 38009b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteSize; 38109b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteUsed; 38209b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = zygoteFree; 38309b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsSize; 38409b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsUsed; 38509b07a96094086e205948717666025909a75163bHiroshi Yamauchi arr[j++] = largeObjectsFree; 38609b07a96094086e205948717666025909a75163bHiroshi Yamauchi env->ReleasePrimitiveArrayCritical(data, arr, 0); 38709b07a96094086e205948717666025909a75163bHiroshi Yamauchi} 38809b07a96094086e205948717666025909a75163bHiroshi Yamauchi 389a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi// The runtime stat names for VMDebug.getRuntimeStat(). 390a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchienum class VMDebugRuntimeStatId { 391a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcGcCount = 0, 392a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcGcTime, 393a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcBytesAllocated, 394a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcBytesFreed, 395a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcBlockingGcCount, 396a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcBlockingGcTime, 397a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcGcCountRateHistogram, 398a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kArtGcBlockingGcCountRateHistogram, 399a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi kNumRuntimeStats, 400a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi}; 401a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 402a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchistatic jobject VMDebug_getRuntimeStatInternal(JNIEnv* env, jclass, jint statId) { 403a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 404a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi switch (static_cast<VMDebugRuntimeStatId>(statId)) { 405a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcGcCount: { 406a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::string output = std::to_string(heap->GetGcCount()); 407a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.c_str()); 408a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 409a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcGcTime: { 410a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::string output = std::to_string(NsToMs(heap->GetGcTime())); 411a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.c_str()); 412a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 413a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcBytesAllocated: { 414a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::string output = std::to_string(heap->GetBytesAllocatedEver()); 415a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.c_str()); 416a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 417a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcBytesFreed: { 418a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::string output = std::to_string(heap->GetBytesFreedEver()); 419a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.c_str()); 420a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 421a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcBlockingGcCount: { 422a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::string output = std::to_string(heap->GetBlockingGcCount()); 423a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.c_str()); 424a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 425a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcBlockingGcTime: { 426a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::string output = std::to_string(NsToMs(heap->GetBlockingGcTime())); 427a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.c_str()); 428a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 429a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcGcCountRateHistogram: { 430a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::ostringstream output; 431a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi heap->DumpGcCountRateHistogram(output); 432a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.str().c_str()); 433a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 434a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi case VMDebugRuntimeStatId::kArtGcBlockingGcCountRateHistogram: { 435a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::ostringstream output; 436a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi heap->DumpBlockingGcCountRateHistogram(output); 437a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return env->NewStringUTF(output.str().c_str()); 438a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 439a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi default: 440a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 441a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 442a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi} 443a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 444ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampestatic bool SetRuntimeStatValue(JNIEnv* env, 445ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe jobjectArray result, 446ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe VMDebugRuntimeStatId id, 447ca620d7bc03b23a0bcf0ef58df58603ee000dca0Andreas Gampe const std::string& value) { 448a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi ScopedLocalRef<jstring> jvalue(env, env->NewStringUTF(value.c_str())); 449a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (jvalue.get() == nullptr) { 450a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return false; 451a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 452a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi env->SetObjectArrayElement(result, static_cast<jint>(id), jvalue.get()); 453a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return true; 454a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi} 455a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 456a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchistatic jobjectArray VMDebug_getRuntimeStatsInternal(JNIEnv* env, jclass) { 457a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi jobjectArray result = env->NewObjectArray( 458a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi static_cast<jint>(VMDebugRuntimeStatId::kNumRuntimeStats), 459a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi WellKnownClasses::java_lang_String, 460a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi nullptr); 461a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (result == nullptr) { 462a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 463a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 464a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 465a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcGcCount, 466a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::to_string(heap->GetGcCount()))) { 467a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 468a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 469a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcGcTime, 470a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::to_string(NsToMs(heap->GetGcTime())))) { 471a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 472a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 473a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBytesAllocated, 474a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::to_string(heap->GetBytesAllocatedEver()))) { 475a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 476a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 477a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBytesFreed, 478a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::to_string(heap->GetBytesFreedEver()))) { 479a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 480a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 481a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBlockingGcCount, 482a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::to_string(heap->GetBlockingGcCount()))) { 483a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 484a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 485a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBlockingGcTime, 486a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::to_string(NsToMs(heap->GetBlockingGcTime())))) { 487a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 488a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 489a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi { 490a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::ostringstream output; 491a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi heap->DumpGcCountRateHistogram(output); 492a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcGcCountRateHistogram, 493a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi output.str())) { 494a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 495a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 496a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 497a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi { 498a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi std::ostringstream output; 499a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi heap->DumpBlockingGcCountRateHistogram(output); 500a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBlockingGcCountRateHistogram, 501a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi output.str())) { 502a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return nullptr; 503a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 504a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi } 505a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi return result; 506a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi} 507a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi 508eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescustatic void VMDebug_attachAgent(JNIEnv* env, jclass, jstring agent) { 509eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu if (agent == nullptr) { 510eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu ScopedObjectAccess soa(env); 511eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu ThrowNullPointerException("agent is null"); 512eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu return; 513eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu } 514eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu 515eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu if (!Dbg::IsJdwpAllowed()) { 516eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu ScopedObjectAccess soa(env); 517eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu ThrowSecurityException("Can't attach agent, process is not debuggable."); 518eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu return; 519eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu } 520eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu 521eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu std::string filename; 522eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu { 523eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu ScopedUtfChars chars(env, agent); 524eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu if (env->ExceptionCheck()) { 525eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu return; 526eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu } 527eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu filename = chars.c_str(); 528eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu } 529eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu 530eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu Runtime::Current()->AttachAgent(filename); 531eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu} 532eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu 5330512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JNINativeMethod gMethods[] = { 5349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"), 535f1820850307f7c2940c758f1232e1c40888a111aMathieu Chartier NATIVE_METHOD(VMDebug, countInstancesOfClasses, "([Ljava/lang/Class;Z)[J"), 5369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, crash, "()V"), 5379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;Ljava/io/FileDescriptor;)V"), 5389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"), 5399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"), 5409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"), 54109b07a96094086e205948717666025909a75163bHiroshi Yamauchi NATIVE_METHOD(VMDebug, getHeapSpaceStats, "([J)V"), 5429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"), 5433b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"), 5449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"), 5459d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, infopoint, "(I)V"), 5463b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMDebug, isDebuggerConnected, "()Z"), 5473b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMDebug, isDebuggingEnabled, "()Z"), 54864caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao NATIVE_METHOD(VMDebug, getMethodTracingMode, "()I"), 5493b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMDebug, lastDebuggerActivity, "()J"), 5503b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMDebug, printLoadedClasses, "(I)V"), 5519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, resetAllocCount, "(I)V"), 5529d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, resetInstructionCount, "()V"), 5539d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startAllocCounting, "()V"), 5549d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"), 5559d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"), 55623009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(IIZI)V"), 557ca6e14ebd19ab972e4962f18d99a882969d7bee1Shukang Zhou NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;Ljava/io/FileDescriptor;IIZIZ)V"), 5584044bdac490777cbc8a12d467bec675ef8aa6eb1Jeff Hao NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;IIZI)V"), 5599d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"), 5609d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopEmulatorTracing, "()V"), 5619d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopInstructionCounting, "()V"), 5629d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes NATIVE_METHOD(VMDebug, stopMethodTracing, "()V"), 5633b6f440dbd066f03a737da6d292074f47b3fbc29Igor Murashkin FAST_NATIVE_METHOD(VMDebug, threadCpuTimeNanos, "()J"), 564a1c9f013c034fbddb9337cc5c7ecf0e5a8b77547Hiroshi Yamauchi NATIVE_METHOD(VMDebug, getRuntimeStatInternal, "(I)Ljava/lang/String;"), 565eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu NATIVE_METHOD(VMDebug, getRuntimeStatsInternal, "()[Ljava/lang/String;"), 566eb84221ffc00357be6d69e2e461c7a45ee96334aLeonard Mosescu NATIVE_METHOD(VMDebug, attachAgent, "(Ljava/lang/String;)V"), 5679d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes}; 5689d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 5699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid register_dalvik_system_VMDebug(JNIEnv* env) { 570eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("dalvik/system/VMDebug"); 5719d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 5729d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 5739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} // namespace art 574