blob: bb6f8bc48654b64deba603f30141933bc8575b52 [file] [log] [blame]
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070017#include <string.h>
18#include <unistd.h>
19
Elliott Hugheseac76672012-05-24 21:56:51 -070020#include "class_linker.h"
21#include "debugger.h"
22#include "hprof/hprof.h"
23#include "jni_internal.h"
24#include "ScopedUtfChars.h"
25#include "toStringArray.h"
26#include "trace.h"
27
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070028namespace art {
29
Elliott Hughes0512f022012-03-15 22:10:52 -070030static jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070031 std::vector<std::string> features;
jeffhaoe343b762011-12-05 16:36:44 -080032 features.push_back("method-trace-profiling");
33 features.push_back("method-trace-profiling-streaming");
Elliott Hughes767a1472011-10-26 18:49:02 -070034 features.push_back("hprof-heap-dump");
35 features.push_back("hprof-heap-dump-streaming");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070036 return toStringArray(env, features);
37}
38
Elliott Hughes0512f022012-03-15 22:10:52 -070039static void VMDebug_startAllocCounting(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070040 Runtime::Current()->SetStatsEnabled(true);
41}
42
Elliott Hughes0512f022012-03-15 22:10:52 -070043static void VMDebug_stopAllocCounting(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070044 Runtime::Current()->SetStatsEnabled(false);
45}
46
Elliott Hughes1bac54f2012-03-16 12:48:31 -070047static jint VMDebug_getAllocCount(JNIEnv*, jclass, jint kind) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070048 return Runtime::Current()->GetStat(kind);
49}
50
Elliott Hughes0512f022012-03-15 22:10:52 -070051static void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070052 Runtime::Current()->ResetStats(kinds);
53}
54
Elliott Hughes1bac54f2012-03-16 12:48:31 -070055static void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags) {
jeffhaoe343b762011-12-05 16:36:44 -080056 Trace::Start("[DDMS]", -1, bufferSize, flags, true);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070057}
58
Elliott Hughes0512f022012-03-15 22:10:52 -070059static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, jobject javaFd, jint bufferSize, jint flags) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070060 int originalFd = jniGetFDFromFileDescriptor(env, javaFd);
61 if (originalFd < 0) {
62 return;
63 }
64
65 int fd = dup(originalFd);
66 if (fd < 0) {
Elliott Hugheseac76672012-05-24 21:56:51 -070067 Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "dup(%d) failed: %s", originalFd, strerror(errno));
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070068 return;
69 }
70
71 ScopedUtfChars traceFilename(env, javaTraceFilename);
72 if (traceFilename.c_str() == NULL) {
73 return;
74 }
jeffhaoe343b762011-12-05 16:36:44 -080075 Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, false);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070076}
77
Elliott Hughes0512f022012-03-15 22:10:52 -070078static void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename, jint bufferSize, jint flags) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070079 ScopedUtfChars traceFilename(env, javaTraceFilename);
80 if (traceFilename.c_str() == NULL) {
81 return;
82 }
jeffhaoe343b762011-12-05 16:36:44 -080083 Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, false);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070084}
85
Elliott Hughes0512f022012-03-15 22:10:52 -070086static jboolean VMDebug_isMethodTracingActive(JNIEnv*, jclass) {
jeffhao2692b572011-12-16 15:42:28 -080087 return Runtime::Current()->IsMethodTracingActive();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070088}
89
Elliott Hughes0512f022012-03-15 22:10:52 -070090static void VMDebug_stopMethodTracing(JNIEnv*, jclass) {
jeffhaoe343b762011-12-05 16:36:44 -080091 Trace::Stop();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070092}
93
Elliott Hughes0512f022012-03-15 22:10:52 -070094static void VMDebug_startEmulatorTracing(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070095 UNIMPLEMENTED(WARNING);
96 //dvmEmulatorTraceStart();
97}
98
Elliott Hughes0512f022012-03-15 22:10:52 -070099static void VMDebug_stopEmulatorTracing(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700100 UNIMPLEMENTED(WARNING);
101 //dvmEmulatorTraceStop();
102}
103
Elliott Hughes0512f022012-03-15 22:10:52 -0700104static jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) {
Elliott Hughesc0f09332012-03-26 13:27:06 -0700105 return Dbg::IsDebuggerActive();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700106}
107
Elliott Hughes0512f022012-03-15 22:10:52 -0700108static jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) {
Elliott Hughesc0f09332012-03-26 13:27:06 -0700109 return Dbg::IsJdwpConfigured();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700110}
111
Elliott Hughes0512f022012-03-15 22:10:52 -0700112static jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700113 return Dbg::LastDebuggerActivity();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700114}
115
Elliott Hugheseac76672012-05-24 21:56:51 -0700116static void VMDebug_startInstructionCounting(JNIEnv*, jclass) {
117 Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700118}
119
Elliott Hugheseac76672012-05-24 21:56:51 -0700120static void VMDebug_stopInstructionCounting(JNIEnv*, jclass) {
121 Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700122}
123
Elliott Hugheseac76672012-05-24 21:56:51 -0700124static void VMDebug_getInstructionCount(JNIEnv*, jclass, jintArray /*javaCounts*/) {
125 Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700126}
127
Elliott Hugheseac76672012-05-24 21:56:51 -0700128static void VMDebug_resetInstructionCount(JNIEnv*, jclass) {
129 Thread::Current()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", "");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700130}
131
Elliott Hughes0512f022012-03-15 22:10:52 -0700132static void VMDebug_printLoadedClasses(JNIEnv*, jclass, jint flags) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700133 return Runtime::Current()->GetClassLinker()->DumpAllClasses(flags);
134}
135
Elliott Hughes0512f022012-03-15 22:10:52 -0700136static jint VMDebug_getLoadedClassCount(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700137 return Runtime::Current()->GetClassLinker()->NumLoadedClasses();
138}
139
140/*
141 * Returns the thread-specific CPU-time clock value for the current thread,
142 * or -1 if the feature isn't supported.
143 */
Elliott Hughes0512f022012-03-15 22:10:52 -0700144static jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) {
145 return ThreadCpuNanoTime();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700146}
147
148/*
149 * static void dumpHprofData(String fileName, FileDescriptor fd)
150 *
151 * Cause "hprof" data to be dumped. We can throw an IOException if an
152 * error occurs during file handling.
153 */
Elliott Hughes0512f022012-03-15 22:10:52 -0700154static void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jobject javaFd) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700155 // Only one of these may be NULL.
156 if (javaFilename == NULL && javaFd == NULL) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700157 Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", "fileName == null && fd == null");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700158 return;
159 }
160
161 std::string filename;
162 if (javaFilename != NULL) {
163 ScopedUtfChars chars(env, javaFilename);
164 if (env->ExceptionCheck()) {
165 return;
166 }
167 filename = chars.c_str();
168 } else {
169 filename = "[fd]";
170 }
171
172 int fd = -1;
173 if (javaFd != NULL) {
174 fd = jniGetFDFromFileDescriptor(env, javaFd);
175 if (fd < 0) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700176 Thread::Current()->ThrowNewException("Ljava/lang/RuntimeException;", "Invalid file descriptor");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700177 return;
178 }
179 }
180
Elliott Hughesfbd84562011-11-07 18:56:13 -0800181 int result = hprof::DumpHeap(filename.c_str(), fd, false);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700182 if (result != 0) {
183 // TODO: ideally we'd throw something more specific based on actual failure
Elliott Hugheseac76672012-05-24 21:56:51 -0700184 Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details: %d", result);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700185 return;
186 }
187}
188
Elliott Hugheseac76672012-05-24 21:56:51 -0700189static void VMDebug_dumpHprofDataDdms(JNIEnv*, jclass) {
Elliott Hughesfbd84562011-11-07 18:56:13 -0800190 int result = hprof::DumpHeap("[DDMS]", -1, true);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700191 if (result != 0) {
192 // TODO: ideally we'd throw something more specific based on actual failure
Elliott Hugheseac76672012-05-24 21:56:51 -0700193 Thread::Current()->ThrowNewExceptionF("Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details: %d", result);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700194 return;
195 }
196}
197
Elliott Hughes0512f022012-03-15 22:10:52 -0700198static void VMDebug_dumpReferenceTables(JNIEnv* env, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700199 LOG(INFO) << "--- reference table dump ---";
200
201 JNIEnvExt* e = reinterpret_cast<JNIEnvExt*>(env);
Elliott Hughes73e66f72012-05-09 09:34:45 -0700202 e->DumpReferenceTables(LOG(INFO));
203 e->vm->DumpReferenceTables(LOG(INFO));
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700204
205 LOG(INFO) << "---";
206}
207
Elliott Hughes0512f022012-03-15 22:10:52 -0700208static void VMDebug_crash(JNIEnv*, jclass) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700209 LOG(FATAL) << "Crashing runtime on request";
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700210}
211
Elliott Hughes0512f022012-03-15 22:10:52 -0700212static void VMDebug_infopoint(JNIEnv*, jclass, jint id) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700213 LOG(INFO) << "VMDebug infopoint " << id << " hit";
214}
215
Elliott Hughes0512f022012-03-15 22:10:52 -0700216static jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass, jboolean countAssignable) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700217 Class* c = Decode<Class*>(env, javaClass);
218 if (c == NULL) {
219 return 0;
220 }
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800221 return Runtime::Current()->GetHeap()->CountInstances(c, countAssignable);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700222}
223
Elliott Hughes0512f022012-03-15 22:10:52 -0700224static JNINativeMethod gMethods[] = {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700225 NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"),
226 NATIVE_METHOD(VMDebug, crash, "()V"),
227 NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;Ljava/io/FileDescriptor;)V"),
228 NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"),
229 NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"),
230 NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"),
231 NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"),
232 NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"),
233 NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"),
234 NATIVE_METHOD(VMDebug, infopoint, "(I)V"),
235 NATIVE_METHOD(VMDebug, isDebuggerConnected, "()Z"),
236 NATIVE_METHOD(VMDebug, isDebuggingEnabled, "()Z"),
237 NATIVE_METHOD(VMDebug, isMethodTracingActive, "()Z"),
238 NATIVE_METHOD(VMDebug, lastDebuggerActivity, "()J"),
239 NATIVE_METHOD(VMDebug, printLoadedClasses, "(I)V"),
240 NATIVE_METHOD(VMDebug, resetAllocCount, "(I)V"),
241 NATIVE_METHOD(VMDebug, resetInstructionCount, "()V"),
242 NATIVE_METHOD(VMDebug, startAllocCounting, "()V"),
243 NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"),
244 NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"),
245 NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(II)V"),
246 NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V"),
247 NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;II)V"),
248 NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"),
249 NATIVE_METHOD(VMDebug, stopEmulatorTracing, "()V"),
250 NATIVE_METHOD(VMDebug, stopInstructionCounting, "()V"),
251 NATIVE_METHOD(VMDebug, stopMethodTracing, "()V"),
252 NATIVE_METHOD(VMDebug, threadCpuTimeNanos, "()J"),
253};
254
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700255void register_dalvik_system_VMDebug(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700256 REGISTER_NATIVE_METHODS("dalvik/system/VMDebug");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700257}
258
259} // namespace art