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