blob: 70dd5cb56d32813a8f30117efb5b89698af578f6 [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
Andreas Gampe277ccbd2014-11-03 21:36:10 -080017#include "dalvik_system_VMDebug.h"
18
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070019#include <string.h>
20#include <unistd.h>
21
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -070022#include <sstream>
23
Andreas Gampea14100c2017-04-24 15:09:56 -070024#include "nativehelper/jni_macros.h"
25
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -070026#include "base/histogram-inl.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010027#include "base/time_utils.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070028#include "class_linker.h"
Ian Rogers62d6c772013-02-27 08:32:07 -080029#include "common_throws.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070030#include "debugger.h"
Mathieu Chartier7410f292013-11-24 13:17:35 -080031#include "gc/space/bump_pointer_space.h"
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -070032#include "gc/space/dlmalloc_space.h"
33#include "gc/space/large_object_space.h"
34#include "gc/space/space-inl.h"
Mathieu Chartier1f3b5352014-02-03 14:00:42 -080035#include "gc/space/zygote_space.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070036#include "handle_scope-inl.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070037#include "hprof/hprof.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070038#include "java_vm_ext.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070039#include "jni_internal.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080040#include "mirror/class.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070041#include "mirror/object_array-inl.h"
Andreas Gampe87583b32017-05-25 11:22:18 -070042#include "native_util.h"
Steven Morelande431e272017-07-18 16:53:49 -070043#include "nativehelper/ScopedLocalRef.h"
44#include "nativehelper/ScopedUtfChars.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070045#include "scoped_fast_native_object_access-inl.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070046#include "trace.h"
Ian Rogersdd157d72014-05-15 14:47:50 -070047#include "well_known_classes.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070048
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070049namespace art {
50
Elliott Hughes0512f022012-03-15 22:10:52 -070051static jobjectArray VMDebug_getVmFeatureList(JNIEnv* env, jclass) {
Ian Rogersdd157d72014-05-15 14:47:50 -070052 static const char* features[] = {
53 "method-trace-profiling",
54 "method-trace-profiling-streaming",
55 "method-sample-profiling",
56 "hprof-heap-dump",
57 "hprof-heap-dump-streaming",
58 };
59 jobjectArray result = env->NewObjectArray(arraysize(features),
60 WellKnownClasses::java_lang_String,
61 nullptr);
62 if (result != nullptr) {
63 for (size_t i = 0; i < arraysize(features); ++i) {
64 ScopedLocalRef<jstring> jfeature(env, env->NewStringUTF(features[i]));
65 if (jfeature.get() == nullptr) {
66 return nullptr;
67 }
68 env->SetObjectArrayElement(result, i, jfeature.get());
69 }
70 }
71 return result;
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070072}
73
Elliott Hughes0512f022012-03-15 22:10:52 -070074static void VMDebug_startAllocCounting(JNIEnv*, jclass) {
Mathieu Chartier9ef78b52014-09-25 17:03:12 -070075 Runtime::Current()->SetStatsEnabled(true);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070076}
77
Elliott Hughes0512f022012-03-15 22:10:52 -070078static void VMDebug_stopAllocCounting(JNIEnv*, jclass) {
Mathieu Chartier9ef78b52014-09-25 17:03:12 -070079 Runtime::Current()->SetStatsEnabled(false);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070080}
81
Elliott Hughes1bac54f2012-03-16 12:48:31 -070082static jint VMDebug_getAllocCount(JNIEnv*, jclass, jint kind) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070083 return Runtime::Current()->GetStat(kind);
84}
85
Elliott Hughes0512f022012-03-15 22:10:52 -070086static void VMDebug_resetAllocCount(JNIEnv*, jclass, jint kinds) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070087 Runtime::Current()->ResetStats(kinds);
88}
89
Jeff Hao23009dc2013-08-22 15:36:42 -070090static void VMDebug_startMethodTracingDdmsImpl(JNIEnv*, jclass, jint bufferSize, jint flags,
91 jboolean samplingEnabled, jint intervalUs) {
Andreas Gampe7e7e0f42015-03-29 15:26:23 -070092 Trace::Start("[DDMS]", -1, bufferSize, flags, Trace::TraceOutputMode::kDDMS,
93 samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing,
94 intervalUs);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -070095}
96
Ian Rogers00f7d0e2012-07-19 15:28:27 -070097static void VMDebug_startMethodTracingFd(JNIEnv* env, jclass, jstring javaTraceFilename,
Andreas Gampead5df102017-10-04 16:31:08 -070098 jint javaFd, jint bufferSize, jint flags,
Shukang Zhouca6e14e2017-01-25 00:35:21 -080099 jboolean samplingEnabled, jint intervalUs,
100 jboolean streamingOutput) {
Andreas Gampead5df102017-10-04 16:31:08 -0700101 int originalFd = javaFd;
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700102 if (originalFd < 0) {
103 return;
104 }
105
106 int fd = dup(originalFd);
107 if (fd < 0) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700108 ScopedObjectAccess soa(env);
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000109 soa.Self()->ThrowNewExceptionF("Ljava/lang/RuntimeException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800110 "dup(%d) failed: %s", originalFd, strerror(errno));
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700111 return;
112 }
113
114 ScopedUtfChars traceFilename(env, javaTraceFilename);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700115 if (traceFilename.c_str() == nullptr) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700116 return;
117 }
Shukang Zhouca6e14e2017-01-25 00:35:21 -0800118 Trace::TraceOutputMode outputMode = streamingOutput
119 ? Trace::TraceOutputMode::kStreaming
120 : Trace::TraceOutputMode::kFile;
121 Trace::Start(traceFilename.c_str(), fd, bufferSize, flags, outputMode,
Andreas Gampe7e7e0f42015-03-29 15:26:23 -0700122 samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing,
123 intervalUs);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700124}
125
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700126static void VMDebug_startMethodTracingFilename(JNIEnv* env, jclass, jstring javaTraceFilename,
Jeff Hao4044bda2014-01-06 15:50:45 -0800127 jint bufferSize, jint flags,
128 jboolean samplingEnabled, jint intervalUs) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700129 ScopedUtfChars traceFilename(env, javaTraceFilename);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700130 if (traceFilename.c_str() == nullptr) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700131 return;
132 }
Andreas Gampe7e7e0f42015-03-29 15:26:23 -0700133 Trace::Start(traceFilename.c_str(), -1, bufferSize, flags, Trace::TraceOutputMode::kFile,
134 samplingEnabled ? Trace::TraceMode::kSampling : Trace::TraceMode::kMethodTracing,
135 intervalUs);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700136}
137
Jeff Hao64caa7d2013-08-29 11:18:01 -0700138static jint VMDebug_getMethodTracingMode(JNIEnv*, jclass) {
139 return Trace::GetMethodTracingMode();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700140}
141
Elliott Hughes0512f022012-03-15 22:10:52 -0700142static void VMDebug_stopMethodTracing(JNIEnv*, jclass) {
jeffhaoe343b762011-12-05 16:36:44 -0800143 Trace::Stop();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700144}
145
Elliott Hughes0512f022012-03-15 22:10:52 -0700146static void VMDebug_startEmulatorTracing(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700147 UNIMPLEMENTED(WARNING);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700148 // dvmEmulatorTraceStart();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700149}
150
Elliott Hughes0512f022012-03-15 22:10:52 -0700151static void VMDebug_stopEmulatorTracing(JNIEnv*, jclass) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700152 UNIMPLEMENTED(WARNING);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700153 // dvmEmulatorTraceStop();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700154}
155
Elliott Hughes0512f022012-03-15 22:10:52 -0700156static jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) {
Elliott Hughesc0f09332012-03-26 13:27:06 -0700157 return Dbg::IsDebuggerActive();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700158}
159
Elliott Hughes0512f022012-03-15 22:10:52 -0700160static jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) {
Elliott Hughesc0f09332012-03-26 13:27:06 -0700161 return Dbg::IsJdwpConfigured();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700162}
163
Elliott Hughes0512f022012-03-15 22:10:52 -0700164static jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) {
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700165 return Dbg::LastDebuggerActivity();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700166}
167
Ian Rogers62d6c772013-02-27 08:32:07 -0800168static void ThrowUnsupportedOperationException(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700169 ScopedObjectAccess soa(env);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700170 soa.Self()->ThrowNewException("Ljava/lang/UnsupportedOperationException;", nullptr);
Ian Rogers62d6c772013-02-27 08:32:07 -0800171}
172
173static void VMDebug_startInstructionCounting(JNIEnv* env, jclass) {
174 ThrowUnsupportedOperationException(env);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700175}
176
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700177static void VMDebug_stopInstructionCounting(JNIEnv* env, jclass) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800178 ThrowUnsupportedOperationException(env);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700179}
180
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700181static void VMDebug_getInstructionCount(JNIEnv* env, jclass, jintArray /*javaCounts*/) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800182 ThrowUnsupportedOperationException(env);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700183}
184
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700185static void VMDebug_resetInstructionCount(JNIEnv* env, jclass) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800186 ThrowUnsupportedOperationException(env);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700187}
188
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700189static void VMDebug_printLoadedClasses(JNIEnv* env, jclass, jint flags) {
Andreas Gampecc1b5352016-12-01 16:58:38 -0800190 class DumpClassVisitor : public ClassVisitor {
191 public:
192 explicit DumpClassVisitor(int dump_flags) : flags_(dump_flags) {}
193
194 bool operator()(ObjPtr<mirror::Class> klass) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
195 klass->DumpClass(LOG_STREAM(ERROR), flags_);
196 return true;
197 }
198
199 private:
200 const int flags_;
201 };
202 DumpClassVisitor visitor(flags);
203
Ian Rogers53b8b092014-03-13 23:45:53 -0700204 ScopedFastNativeObjectAccess soa(env);
Andreas Gampecc1b5352016-12-01 16:58:38 -0800205 return Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700206}
207
Ian Rogers7dfb28c2013-08-22 08:18:36 -0700208static jint VMDebug_getLoadedClassCount(JNIEnv* env, jclass) {
Ian Rogers53b8b092014-03-13 23:45:53 -0700209 ScopedFastNativeObjectAccess soa(env);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700210 return Runtime::Current()->GetClassLinker()->NumLoadedClasses();
211}
212
213/*
214 * Returns the thread-specific CPU-time clock value for the current thread,
215 * or -1 if the feature isn't supported.
216 */
Elliott Hughes0512f022012-03-15 22:10:52 -0700217static jlong VMDebug_threadCpuTimeNanos(JNIEnv*, jclass) {
218 return ThreadCpuNanoTime();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700219}
220
221/*
222 * static void dumpHprofData(String fileName, FileDescriptor fd)
223 *
224 * Cause "hprof" data to be dumped. We can throw an IOException if an
225 * error occurs during file handling.
226 */
Andreas Gampead5df102017-10-04 16:31:08 -0700227static void VMDebug_dumpHprofData(JNIEnv* env, jclass, jstring javaFilename, jint javaFd) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700228 // Only one of these may be null.
Andreas Gampead5df102017-10-04 16:31:08 -0700229 if (javaFilename == nullptr && javaFd < 0) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700230 ScopedObjectAccess soa(env);
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000231 ThrowNullPointerException("fileName == null && fd == null");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700232 return;
233 }
234
235 std::string filename;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700236 if (javaFilename != nullptr) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700237 ScopedUtfChars chars(env, javaFilename);
238 if (env->ExceptionCheck()) {
239 return;
240 }
241 filename = chars.c_str();
242 } else {
243 filename = "[fd]";
244 }
245
Andreas Gampead5df102017-10-04 16:31:08 -0700246 int fd = javaFd;
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700247
Elliott Hughes622a6982012-06-08 17:58:54 -0700248 hprof::DumpHeap(filename.c_str(), fd, false);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700249}
250
Elliott Hugheseac76672012-05-24 21:56:51 -0700251static void VMDebug_dumpHprofDataDdms(JNIEnv*, jclass) {
Elliott Hughes622a6982012-06-08 17:58:54 -0700252 hprof::DumpHeap("[DDMS]", -1, true);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700253}
254
Elliott Hughes0512f022012-03-15 22:10:52 -0700255static void VMDebug_dumpReferenceTables(JNIEnv* env, jclass) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700256 ScopedObjectAccess soa(env);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700257 LOG(INFO) << "--- reference table dump ---";
258
Andreas Gampe3fec9ac2016-09-13 10:47:28 -0700259 soa.Env()->DumpReferenceTables(LOG_STREAM(INFO));
260 soa.Vm()->DumpReferenceTables(LOG_STREAM(INFO));
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700261
262 LOG(INFO) << "---";
263}
264
Elliott Hughes0512f022012-03-15 22:10:52 -0700265static void VMDebug_crash(JNIEnv*, jclass) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700266 LOG(FATAL) << "Crashing runtime on request";
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700267}
268
Elliott Hughes0512f022012-03-15 22:10:52 -0700269static void VMDebug_infopoint(JNIEnv*, jclass, jint id) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700270 LOG(INFO) << "VMDebug infopoint " << id << " hit";
271}
272
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700273static jlong VMDebug_countInstancesOfClass(JNIEnv* env,
274 jclass,
275 jclass javaClass,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700276 jboolean countAssignable) {
277 ScopedObjectAccess soa(env);
Mathieu Chartierf1820852015-07-10 13:19:51 -0700278 gc::Heap* const heap = Runtime::Current()->GetHeap();
279 // Caller's responsibility to do GC if desired.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700280 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(javaClass);
Mathieu Chartier412c7fc2014-02-07 12:18:39 -0800281 if (c == nullptr) {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700282 return 0;
283 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700284 VariableSizedHandleScope hs(soa.Self());
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700285 std::vector<Handle<mirror::Class>> classes {hs.NewHandle(c)};
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800286 uint64_t count = 0;
Mathieu Chartier412c7fc2014-02-07 12:18:39 -0800287 heap->CountInstances(classes, countAssignable, &count);
Elliott Hughesec0f83d2013-01-15 16:54:08 -0800288 return count;
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700289}
290
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700291static jlongArray VMDebug_countInstancesOfClasses(JNIEnv* env,
292 jclass,
293 jobjectArray javaClasses,
Mathieu Chartierf1820852015-07-10 13:19:51 -0700294 jboolean countAssignable) {
295 ScopedObjectAccess soa(env);
296 gc::Heap* const heap = Runtime::Current()->GetHeap();
297 // Caller's responsibility to do GC if desired.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700298 ObjPtr<mirror::ObjectArray<mirror::Class>> decoded_classes =
299 soa.Decode<mirror::ObjectArray<mirror::Class>>(javaClasses);
Mathieu Chartierf1820852015-07-10 13:19:51 -0700300 if (decoded_classes == nullptr) {
301 return nullptr;
302 }
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700303 VariableSizedHandleScope hs(soa.Self());
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700304 std::vector<Handle<mirror::Class>> classes;
Mathieu Chartierf1820852015-07-10 13:19:51 -0700305 for (size_t i = 0, count = decoded_classes->GetLength(); i < count; ++i) {
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700306 classes.push_back(hs.NewHandle(decoded_classes->Get(i)));
Mathieu Chartierf1820852015-07-10 13:19:51 -0700307 }
308 std::vector<uint64_t> counts(classes.size(), 0u);
309 // Heap::CountInstances can handle null and will put 0 for these classes.
310 heap->CountInstances(classes, countAssignable, &counts[0]);
Mathieu Chartier9d156d52016-10-06 17:44:26 -0700311 ObjPtr<mirror::LongArray> long_counts = mirror::LongArray::Alloc(soa.Self(), counts.size());
Mathieu Chartierf1820852015-07-10 13:19:51 -0700312 if (long_counts == nullptr) {
313 soa.Self()->AssertPendingOOMException();
314 return nullptr;
315 }
316 for (size_t i = 0; i < counts.size(); ++i) {
317 long_counts->Set(i, counts[i]);
318 }
319 return soa.AddLocalReference<jlongArray>(long_counts);
320}
321
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -0700322// We export the VM internal per-heap-space size/alloc/free metrics
323// for the zygote space, alloc space (application heap), and the large
324// object space for dumpsys meminfo. The other memory region data such
325// as PSS, private/shared dirty/shared data are available via
326// /proc/<pid>/smaps.
327static void VMDebug_getHeapSpaceStats(JNIEnv* env, jclass, jlongArray data) {
Ian Rogers6b99dd12013-07-25 12:11:32 -0700328 jlong* arr = reinterpret_cast<jlong*>(env->GetPrimitiveArrayCritical(data, 0));
Mathieu Chartier7410f292013-11-24 13:17:35 -0800329 if (arr == nullptr || env->GetArrayLength(data) < 9) {
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -0700330 return;
331 }
332
333 size_t allocSize = 0;
334 size_t allocUsed = 0;
335 size_t zygoteSize = 0;
336 size_t zygoteUsed = 0;
337 size_t largeObjectsSize = 0;
338 size_t largeObjectsUsed = 0;
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -0700339 gc::Heap* heap = Runtime::Current()->GetHeap();
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -0800340 {
341 ScopedObjectAccess soa(env);
342 for (gc::space::ContinuousSpace* space : heap->GetContinuousSpaces()) {
343 if (space->IsImageSpace()) {
344 // Currently don't include the image space.
345 } else if (space->IsZygoteSpace()) {
346 gc::space::ZygoteSpace* zygote_space = space->AsZygoteSpace();
347 zygoteSize += zygote_space->Size();
348 zygoteUsed += zygote_space->GetBytesAllocated();
349 } else if (space->IsMallocSpace()) {
350 // This is a malloc space.
351 gc::space::MallocSpace* malloc_space = space->AsMallocSpace();
352 allocSize += malloc_space->GetFootprint();
353 allocUsed += malloc_space->GetBytesAllocated();
354 } else if (space->IsBumpPointerSpace()) {
355 gc::space::BumpPointerSpace* bump_pointer_space = space->AsBumpPointerSpace();
356 allocSize += bump_pointer_space->Size();
357 allocUsed += bump_pointer_space->GetBytesAllocated();
358 }
359 }
360 for (gc::space::DiscontinuousSpace* space : heap->GetDiscontinuousSpaces()) {
361 if (space->IsLargeObjectSpace()) {
362 largeObjectsSize += space->AsLargeObjectSpace()->GetBytesAllocated();
363 largeObjectsUsed += largeObjectsSize;
364 }
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -0700365 }
366 }
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -0700367 size_t allocFree = allocSize - allocUsed;
368 size_t zygoteFree = zygoteSize - zygoteUsed;
369 size_t largeObjectsFree = largeObjectsSize - largeObjectsUsed;
370
371 int j = 0;
372 arr[j++] = allocSize;
373 arr[j++] = allocUsed;
374 arr[j++] = allocFree;
375 arr[j++] = zygoteSize;
376 arr[j++] = zygoteUsed;
377 arr[j++] = zygoteFree;
378 arr[j++] = largeObjectsSize;
379 arr[j++] = largeObjectsUsed;
380 arr[j++] = largeObjectsFree;
381 env->ReleasePrimitiveArrayCritical(data, arr, 0);
382}
383
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700384// The runtime stat names for VMDebug.getRuntimeStat().
385enum class VMDebugRuntimeStatId {
386 kArtGcGcCount = 0,
387 kArtGcGcTime,
388 kArtGcBytesAllocated,
389 kArtGcBytesFreed,
390 kArtGcBlockingGcCount,
391 kArtGcBlockingGcTime,
392 kArtGcGcCountRateHistogram,
393 kArtGcBlockingGcCountRateHistogram,
394 kNumRuntimeStats,
395};
396
397static jobject VMDebug_getRuntimeStatInternal(JNIEnv* env, jclass, jint statId) {
398 gc::Heap* heap = Runtime::Current()->GetHeap();
399 switch (static_cast<VMDebugRuntimeStatId>(statId)) {
400 case VMDebugRuntimeStatId::kArtGcGcCount: {
401 std::string output = std::to_string(heap->GetGcCount());
402 return env->NewStringUTF(output.c_str());
403 }
404 case VMDebugRuntimeStatId::kArtGcGcTime: {
405 std::string output = std::to_string(NsToMs(heap->GetGcTime()));
406 return env->NewStringUTF(output.c_str());
407 }
408 case VMDebugRuntimeStatId::kArtGcBytesAllocated: {
409 std::string output = std::to_string(heap->GetBytesAllocatedEver());
410 return env->NewStringUTF(output.c_str());
411 }
412 case VMDebugRuntimeStatId::kArtGcBytesFreed: {
413 std::string output = std::to_string(heap->GetBytesFreedEver());
414 return env->NewStringUTF(output.c_str());
415 }
416 case VMDebugRuntimeStatId::kArtGcBlockingGcCount: {
417 std::string output = std::to_string(heap->GetBlockingGcCount());
418 return env->NewStringUTF(output.c_str());
419 }
420 case VMDebugRuntimeStatId::kArtGcBlockingGcTime: {
421 std::string output = std::to_string(NsToMs(heap->GetBlockingGcTime()));
422 return env->NewStringUTF(output.c_str());
423 }
424 case VMDebugRuntimeStatId::kArtGcGcCountRateHistogram: {
425 std::ostringstream output;
426 heap->DumpGcCountRateHistogram(output);
427 return env->NewStringUTF(output.str().c_str());
428 }
429 case VMDebugRuntimeStatId::kArtGcBlockingGcCountRateHistogram: {
430 std::ostringstream output;
431 heap->DumpBlockingGcCountRateHistogram(output);
432 return env->NewStringUTF(output.str().c_str());
433 }
434 default:
435 return nullptr;
436 }
437}
438
Andreas Gampeca620d72016-11-08 08:09:33 -0800439static bool SetRuntimeStatValue(JNIEnv* env,
440 jobjectArray result,
441 VMDebugRuntimeStatId id,
442 const std::string& value) {
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700443 ScopedLocalRef<jstring> jvalue(env, env->NewStringUTF(value.c_str()));
444 if (jvalue.get() == nullptr) {
445 return false;
446 }
447 env->SetObjectArrayElement(result, static_cast<jint>(id), jvalue.get());
448 return true;
449}
450
451static jobjectArray VMDebug_getRuntimeStatsInternal(JNIEnv* env, jclass) {
452 jobjectArray result = env->NewObjectArray(
453 static_cast<jint>(VMDebugRuntimeStatId::kNumRuntimeStats),
454 WellKnownClasses::java_lang_String,
455 nullptr);
456 if (result == nullptr) {
457 return nullptr;
458 }
459 gc::Heap* heap = Runtime::Current()->GetHeap();
460 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcGcCount,
461 std::to_string(heap->GetGcCount()))) {
462 return nullptr;
463 }
464 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcGcTime,
465 std::to_string(NsToMs(heap->GetGcTime())))) {
466 return nullptr;
467 }
468 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBytesAllocated,
469 std::to_string(heap->GetBytesAllocatedEver()))) {
470 return nullptr;
471 }
472 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBytesFreed,
473 std::to_string(heap->GetBytesFreedEver()))) {
474 return nullptr;
475 }
476 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBlockingGcCount,
477 std::to_string(heap->GetBlockingGcCount()))) {
478 return nullptr;
479 }
480 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBlockingGcTime,
481 std::to_string(NsToMs(heap->GetBlockingGcTime())))) {
482 return nullptr;
483 }
484 {
485 std::ostringstream output;
486 heap->DumpGcCountRateHistogram(output);
487 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcGcCountRateHistogram,
488 output.str())) {
489 return nullptr;
490 }
491 }
492 {
493 std::ostringstream output;
494 heap->DumpBlockingGcCountRateHistogram(output);
495 if (!SetRuntimeStatValue(env, result, VMDebugRuntimeStatId::kArtGcBlockingGcCountRateHistogram,
496 output.str())) {
497 return nullptr;
498 }
499 }
500 return result;
501}
502
Leonard Mosescueb842212016-10-06 17:26:36 -0700503static void VMDebug_attachAgent(JNIEnv* env, jclass, jstring agent) {
504 if (agent == nullptr) {
505 ScopedObjectAccess soa(env);
506 ThrowNullPointerException("agent is null");
507 return;
508 }
509
510 if (!Dbg::IsJdwpAllowed()) {
511 ScopedObjectAccess soa(env);
512 ThrowSecurityException("Can't attach agent, process is not debuggable.");
513 return;
514 }
515
516 std::string filename;
517 {
518 ScopedUtfChars chars(env, agent);
519 if (env->ExceptionCheck()) {
520 return;
521 }
522 filename = chars.c_str();
523 }
524
525 Runtime::Current()->AttachAgent(filename);
526}
527
Elliott Hughes0512f022012-03-15 22:10:52 -0700528static JNINativeMethod gMethods[] = {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700529 NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"),
Mathieu Chartierf1820852015-07-10 13:19:51 -0700530 NATIVE_METHOD(VMDebug, countInstancesOfClasses, "([Ljava/lang/Class;Z)[J"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700531 NATIVE_METHOD(VMDebug, crash, "()V"),
Andreas Gampead5df102017-10-04 16:31:08 -0700532 NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;I)V"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700533 NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"),
534 NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"),
535 NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"),
Hiroshi Yamauchi09b07a92013-07-15 13:17:06 -0700536 NATIVE_METHOD(VMDebug, getHeapSpaceStats, "([J)V"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700537 NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800538 FAST_NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700539 NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"),
540 NATIVE_METHOD(VMDebug, infopoint, "(I)V"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800541 FAST_NATIVE_METHOD(VMDebug, isDebuggerConnected, "()Z"),
542 FAST_NATIVE_METHOD(VMDebug, isDebuggingEnabled, "()Z"),
Jeff Hao64caa7d2013-08-29 11:18:01 -0700543 NATIVE_METHOD(VMDebug, getMethodTracingMode, "()I"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800544 FAST_NATIVE_METHOD(VMDebug, lastDebuggerActivity, "()J"),
545 FAST_NATIVE_METHOD(VMDebug, printLoadedClasses, "(I)V"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700546 NATIVE_METHOD(VMDebug, resetAllocCount, "(I)V"),
547 NATIVE_METHOD(VMDebug, resetInstructionCount, "()V"),
548 NATIVE_METHOD(VMDebug, startAllocCounting, "()V"),
549 NATIVE_METHOD(VMDebug, startEmulatorTracing, "()V"),
550 NATIVE_METHOD(VMDebug, startInstructionCounting, "()V"),
Jeff Hao23009dc2013-08-22 15:36:42 -0700551 NATIVE_METHOD(VMDebug, startMethodTracingDdmsImpl, "(IIZI)V"),
Andreas Gampead5df102017-10-04 16:31:08 -0700552 NATIVE_METHOD(VMDebug, startMethodTracingFd, "(Ljava/lang/String;IIIZIZ)V"),
Jeff Hao4044bda2014-01-06 15:50:45 -0800553 NATIVE_METHOD(VMDebug, startMethodTracingFilename, "(Ljava/lang/String;IIZI)V"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700554 NATIVE_METHOD(VMDebug, stopAllocCounting, "()V"),
555 NATIVE_METHOD(VMDebug, stopEmulatorTracing, "()V"),
556 NATIVE_METHOD(VMDebug, stopInstructionCounting, "()V"),
557 NATIVE_METHOD(VMDebug, stopMethodTracing, "()V"),
Igor Murashkin3b6f4402017-02-16 16:13:17 -0800558 FAST_NATIVE_METHOD(VMDebug, threadCpuTimeNanos, "()J"),
Hiroshi Yamauchia1c9f012015-04-02 10:18:12 -0700559 NATIVE_METHOD(VMDebug, getRuntimeStatInternal, "(I)Ljava/lang/String;"),
Leonard Mosescueb842212016-10-06 17:26:36 -0700560 NATIVE_METHOD(VMDebug, getRuntimeStatsInternal, "()[Ljava/lang/String;"),
561 NATIVE_METHOD(VMDebug, attachAgent, "(Ljava/lang/String;)V"),
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700562};
563
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700564void register_dalvik_system_VMDebug(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700565 REGISTER_NATIVE_METHODS("dalvik/system/VMDebug");
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700566}
567
568} // namespace art