blob: 4537a6979a4df2f765ee43353335ad0b2158dda3 [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
17#include "class_linker.h"
Elliott Hughes872d4ec2011-10-21 17:07:15 -070018#include "debugger.h"
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070019#include "jni_internal.h"
20#include "ScopedUtfChars.h"
21#include "toStringArray.h"
22
23#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
24
25#include <string.h>
26#include <unistd.h>
27
28namespace art {
29
30namespace {
31
32/*
33 * Return a set of strings describing available VM features (this is chiefly
34 * of interest to DDMS).
35 */
36jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) {
37 std::vector<std::string> features;
38 //features.push_back("method-trace-profiling");
39 //features.push_back("method-trace-profiling-streaming");
40 //features.push_back("hprof-heap-dump");
41 //features.push_back("hprof-heap-dump-streaming");
42 return toStringArray(env, features);
43}
44
45void VMDebug_startAllocCounting(JNIEnv*, jclass) {
46 Runtime::Current()->SetStatsEnabled(true);
47}
48
49void VMDebug_stopAllocCounting(JNIEnv*, jclass) {
50 Runtime::Current()->SetStatsEnabled(false);
51}
52
53jint VMDebug_getAllocCount(JNIEnv* env, jclass, jint kind) {
54 return Runtime::Current()->GetStat(kind);
55}
56
57void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) {
58 Runtime::Current()->ResetStats(kinds);
59}
60
61void VMDebug_startMethodTracingDdmsImpl(JNIEnv* env, jclass, jint bufferSize, jint flags) {
62 UNIMPLEMENTED(WARNING);
63 //dvmMethodTraceStart("[DDMS]", -1, bufferSize, flags, true);
64}
65
66void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename, jobject javaFd, jint bufferSize, jint flags) {
67 int originalFd = jniGetFDFromFileDescriptor(env, javaFd);
68 if (originalFd < 0) {
69 return;
70 }
71
72 int fd = dup(originalFd);
73 if (fd < 0) {
74 jniThrowExceptionFmt(env, "java/lang/RuntimeException", "dup(%d) failed: %s", originalFd, strerror(errno));
75 return;
76 }
77
78 ScopedUtfChars traceFilename(env, javaTraceFilename);
79 if (traceFilename.c_str() == NULL) {
80 return;
81 }
82 UNIMPLEMENTED(WARNING);
83 //dvmMethodTraceStart(traceFilename.c_str(), fd, bufferSize, flags, false);
84}
85
86void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename, jint bufferSize, jint flags) {
87 ScopedUtfChars traceFilename(env, javaTraceFilename);
88 if (traceFilename.c_str() == NULL) {
89 return;
90 }
91 UNIMPLEMENTED(WARNING);
92 //dvmMethodTraceStart(traceFilename.c_str(), -1, bufferSize, flags, false);
93}
94
95jboolean VMDebug_isMethodTracingActive(JNIEnv*, jclass) {
96 UNIMPLEMENTED(WARNING);
97 return JNI_FALSE; //dvmIsMethodTraceActive();
98}
99
100void VMDebug_stopMethodTracing(JNIEnv*, jclass) {
101 UNIMPLEMENTED(WARNING);
102 //dvmMethodTraceStop();
103}
104
105void VMDebug_startEmulatorTracing(JNIEnv*, jclass) {
106 UNIMPLEMENTED(WARNING);
107 //dvmEmulatorTraceStart();
108}
109
110void VMDebug_stopEmulatorTracing(JNIEnv*, jclass) {
111 UNIMPLEMENTED(WARNING);
112 //dvmEmulatorTraceStop();
113}
114
115jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700116 return Dbg::IsDebuggerConnected();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700117}
118
119jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700120 return Dbg::IsDebuggingEnabled();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700121}
122
123jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700124 return Dbg::LastDebuggerActivity();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700125}
126
127void VMDebug_startInstructionCounting(JNIEnv* env, jclass) {
128 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
129}
130
131void VMDebug_stopInstructionCounting(JNIEnv* env, jclass) {
132 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
133}
134
135void VMDebug_getInstructionCount(JNIEnv* env, jclass, jintArray javaCounts) {
136 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
137}
138
139void VMDebug_resetInstructionCount(JNIEnv* env, jclass) {
140 jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
141}
142
143void VMDebug_printLoadedClasses(JNIEnv*, jclass, jint flags) {
144 return Runtime::Current()->GetClassLinker()->DumpAllClasses(flags);
145}
146
147jint VMDebug_getLoadedClassCount(JNIEnv*, jclass) {
148 return Runtime::Current()->GetClassLinker()->NumLoadedClasses();
149}
150
151/*
152 * Returns the thread-specific CPU-time clock value for the current thread,
153 * or -1 if the feature isn't supported.
154 */
155jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) {
156#ifdef HAVE_POSIX_CLOCKS
157 struct timespec now;
158 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
159 return static_cast<jlong>(now.tv_sec*1000000000LL + now.tv_nsec);
160#else
161 return -1LL;
162#endif
163}
164
165/*
166 * static void dumpHprofData(String fileName, FileDescriptor fd)
167 *
168 * Cause "hprof" data to be dumped. We can throw an IOException if an
169 * error occurs during file handling.
170 */
171void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jobject javaFd) {
172 // Only one of these may be NULL.
173 if (javaFilename == NULL && javaFd == NULL) {
174 jniThrowNullPointerException(env, "fileName == null && fd == null");
175 return;
176 }
177
178 std::string filename;
179 if (javaFilename != NULL) {
180 ScopedUtfChars chars(env, javaFilename);
181 if (env->ExceptionCheck()) {
182 return;
183 }
184 filename = chars.c_str();
185 } else {
186 filename = "[fd]";
187 }
188
189 int fd = -1;
190 if (javaFd != NULL) {
191 fd = jniGetFDFromFileDescriptor(env, javaFd);
192 if (fd < 0) {
193 jniThrowException(env, "Ljava/lang/RuntimeException;", "Invalid file descriptor");
194 return;
195 }
196 }
197
198 UNIMPLEMENTED(WARNING);
199 int result = 0; //hprofDumpHeap(filename.c_str(), fd, false);
200 if (result != 0) {
201 // TODO: ideally we'd throw something more specific based on actual failure
202 jniThrowException(env, "Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details");
203 return;
204 }
205}
206
207void VMDebug_dumpHprofDataDdms(JNIEnv* env, jclass) {
208 UNIMPLEMENTED(WARNING);
209 int result = 0; //hprofDumpHeap("[DDMS]", -1, true);
210 if (result != 0) {
211 // TODO: ideally we'd throw something more specific based on actual failure
212 jniThrowException(env, "Ljava/lang/RuntimeException;", "Failure during heap dump; check log output for details");
213 return;
214 }
215}
216
217void VMDebug_dumpReferenceTables(JNIEnv* env, jclass) {
218 LOG(INFO) << "--- reference table dump ---";
219
220 JNIEnvExt* e = reinterpret_cast<JNIEnvExt*>(env);
221 e->DumpReferenceTables();
222 e->vm->DumpReferenceTables();
223
224 LOG(INFO) << "---";
225}
226
227/*
228 * Dump the current thread's interpreted stack and abort the VM. Useful
229 * for seeing both interpreted and native stack traces.
230 */
231void VMDebug_crash(JNIEnv*, jclass) {
Elliott Hughes3b6baaa2011-10-14 19:13:56 -0700232 std::ostringstream os;
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700233 os << "Crashing VM on request:\n";
234 Thread::Current()->Dump(os);
235 LOG(FATAL) << os.str();
236}
237
238/*
239 * Provide a hook for gdb to hang to so that the VM can be stopped when
240 * user-tagged source locations are being executed.
241 */
242void VMDebug_infopoint(JNIEnv*, jclass, jint id) {
243 LOG(INFO) << "VMDebug infopoint " << id << " hit";
244}
245
246jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass, jboolean countAssignable) {
247 Class* c = Decode<Class*>(env, javaClass);
248 if (c == NULL) {
249 return 0;
250 }
251 return Heap::CountInstances(c, countAssignable);
252}
253
254JNINativeMethod gMethods[] = {
255 NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"),
256 NATIVE_METHOD(VMDebug, crash, "()V"),
257 NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;Ljava/io/FileDescriptor;)V"),
258 NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"),
259 NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"),
260 NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"),
261 NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"),
262 NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"),
263 NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"),
264 NATIVE_METHOD(VMDebug, infopoint, "(I)V"),
265 NATIVE_METHOD(VMDebug, isDebuggerConnected, "()Z"),
266 NATIVE_METHOD(VMDebug, isDebuggingEnabled, "()Z"),
267 NATIVE_METHOD(VMDebug, isMethodTracingActive, "()Z"),
268 NATIVE_METHOD(VMDebug, lastDebuggerActivity, "()J"),
269 NATIVE_METHOD(VMDebug, printLoadedClasses, "(I)V"),
270 NATIVE_METHOD(VMDebug, resetAllocCount, "(I)V"),
271 NATIVE_METHOD(VMDebug, resetInstructionCount, "()V"),
272 NATIVE_METHOD(VMDebug, startAllocCounting, "()V"),
273 NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"),
274 NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"),
275 NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(II)V"),
276 NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V"),
277 NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;II)V"),
278 NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"),
279 NATIVE_METHOD(VMDebug, stopEmulatorTracing, "()V"),
280 NATIVE_METHOD(VMDebug, stopInstructionCounting, "()V"),
281 NATIVE_METHOD(VMDebug, stopMethodTracing, "()V"),
282 NATIVE_METHOD(VMDebug, threadCpuTimeNanos, "()J"),
283};
284
285} // namespace
286
287void register_dalvik_system_VMDebug(JNIEnv* env) {
288 jniRegisterNativeMethods(env, "dalvik/system/VMDebug", gMethods, NELEM(gMethods));
289}
290
291} // namespace art