-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathretained_size_by_classes.cpp
More file actions
113 lines (89 loc) · 4.49 KB
/
retained_size_by_classes.cpp
File metadata and controls
113 lines (89 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include <vector>
#include "retained_size_by_classes.h"
#include "sizes_tags.h"
#include "retained_size_action.h"
jint JNICALL visitObject(jlong classTag, jlong size, jlong *tagPtr, jint length, void *userData) {
if (*tagPtr == 0) {
return JVMTI_ITERATION_CONTINUE;
}
Tag *tag = tagToPointer(*tagPtr);
for (query_size_t i = 0; i < tag->array.getSize(); i++) {
const TagInfoArray::TagInfo &info = tag->array[i];
if (isRetained(info.state)) {
reinterpret_cast<jlong *>(userData)[info.index] += size;
}
}
return JVMTI_ITERATION_CONTINUE;
}
jint JNICALL countHeapSize(jlong classTag, jlong size, jlong *tagPtr, jint length, void *userData) {
*reinterpret_cast<jlong*>(userData) += size;
return JVMTI_ITERATION_CONTINUE;
}
jint JNICALL visitObjectForShallowAndRetainedSize(jlong classTag, jlong size, jlong *tagPtr, jint length, void *userData) {
if (*tagPtr == 0) {
return JVMTI_ITERATION_CONTINUE;
}
Tag *tag = tagToPointer(*tagPtr);
for (query_size_t i = 0; i < tag->array.getSize(); i++) {
const TagInfoArray::TagInfo &info = tag->array[i];
auto *arrays = reinterpret_cast<std::pair<jlong *, jlong *> *>(userData);
if (isRetained(info.state)) {
arrays->second[info.index] += size;
}
if (isStartObject(info.state)) {
arrays->first[info.index] += size;
}
}
return JVMTI_ITERATION_CONTINUE;
}
RetainedSizeByClassesAction::RetainedSizeByClassesAction(JNIEnv *env, jvmtiEnv *jvmti, jobject object) : RetainedSizeAction(env, jvmti, object) {
}
jvmtiError RetainedSizeByClassesAction::getRetainedSizeByClasses(jobjectArray classesArray, std::vector<jlong> &result) {
jvmtiError err = tagObjectsOfClasses(classesArray);
if (!isOk(err)) return err;
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR;
err = tagHeap();
if (!isOk(err)) return err;
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR;
result.resize(env->GetArrayLength(classesArray));
return IterateThroughHeap(JVMTI_HEAP_FILTER_UNTAGGED, nullptr, visitObject, result.data(), "calculate retained sizes");
}
jlongArray RetainedSizeByClassesAction::executeOperation(jobjectArray classesArray) {
std::vector<jlong> result;
jvmtiError err = getRetainedSizeByClasses(classesArray, result);
if (!isOk(err)) {
handleError(jvmti, err, "Could not estimate retained size by classes");
return env->NewLongArray(0);
}
return toJavaArray(env, result);
}
RetainedAndShallowSizeByClassesAction::RetainedAndShallowSizeByClassesAction(JNIEnv *env, jvmtiEnv *jvmti, jobject object) : RetainedSizeAction(env, jvmti, object) {
}
jvmtiError RetainedAndShallowSizeByClassesAction::getShallowAndRetainedSizeByClasses(jobjectArray classesArray,
std::vector<jlong> &shallowSizes,
std::vector<jlong> &retainedSizes) {
jvmtiError err = tagObjectsOfClasses(classesArray);
if (!isOk(err)) return err;
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR;
err = tagHeap();
if (!isOk(err)) return err;
if (shouldStopExecution()) return MEMORY_AGENT_INTERRUPTED_ERROR;
retainedSizes.resize(env->GetArrayLength(classesArray));
shallowSizes.resize(env->GetArrayLength(classesArray));
std::pair<jlong *, jlong *> arrays = std::make_pair(shallowSizes.data(), retainedSizes.data());
return IterateThroughHeap(JVMTI_HEAP_FILTER_UNTAGGED, nullptr, visitObjectForShallowAndRetainedSize, &arrays, "calculate shallow and retained sizes");
}
jobjectArray RetainedAndShallowSizeByClassesAction::executeOperation(jobjectArray classesArray) {
std::vector<jlong> shallowSizes;
std::vector<jlong> retainedSizes;
jvmtiError err = getShallowAndRetainedSizeByClasses(classesArray,shallowSizes, retainedSizes);
jclass langObject = env->FindClass("java/lang/Object");
jobjectArray result = env->NewObjectArray(2, langObject, nullptr);
env->SetObjectArrayElement(result, 0, toJavaArray(env, shallowSizes));
env->SetObjectArrayElement(result, 1, toJavaArray(env, retainedSizes));
if (!isOk(err)) {
handleError(jvmti, err, "Could not estimate retained size by classes");
}
return result;
}