annotate src/share/vm/prims/jvmtiTagMap.cpp @ 10241:d17700c82d7d

8006088: Incompatible heap size flags accepted by VM Summary: Make processing of minimum, initial and maximum heap size more intiutive by removing previous limitations on allowed values, and make error reporting consistent. Further, fix errors in ergonomic heap sizing. Reviewed-by: johnc, jwilhelm, tamao
author tschatzl
date Mon, 06 May 2013 17:19:42 +0200
parents 746b070f5022
children 92ef81e2f571
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
4929
2b150750d53d 7130993: nsk/jdi/ReferenceType/instances/instances004 fails with JFR: assert(ServiceUtil::visible_oop(obj))
sspitsyn
parents: 3816
diff changeset
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1142
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "classfile/symbolTable.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "jvmtifiles/jvmtiEnv.hpp"
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
30 #include "oops/instanceMirrorKlass.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "oops/objArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "oops/oop.inline2.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "prims/jvmtiEventController.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34 #include "prims/jvmtiEventController.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
35 #include "prims/jvmtiExport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "prims/jvmtiImpl.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "prims/jvmtiTagMap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 #include "runtime/biasedLocking.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
40 #include "runtime/jniHandles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
41 #include "runtime/mutex.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
42 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
43 #include "runtime/reflectionUtils.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
44 #include "runtime/vframe.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
45 #include "runtime/vmThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
46 #include "runtime/vm_operations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
47 #include "services/serviceUtil.hpp"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6983
diff changeset
48 #include "utilities/macros.hpp"
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6983
diff changeset
49 #if INCLUDE_ALL_GCS
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
50 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 6983
diff changeset
51 #endif // INCLUDE_ALL_GCS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // JvmtiTagHashmapEntry
a61af66fc99e Initial load
duke
parents:
diff changeset
54 //
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
55 // Each entry encapsulates a reference to the tagged object
0
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // and the tag value. In addition an entry includes a next pointer which
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // is used to chain entries together.
a61af66fc99e Initial load
duke
parents:
diff changeset
58
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
59 class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
60 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
61 friend class JvmtiTagMap;
a61af66fc99e Initial load
duke
parents:
diff changeset
62
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
63 oop _object; // tagged object
0
a61af66fc99e Initial load
duke
parents:
diff changeset
64 jlong _tag; // the tag
a61af66fc99e Initial load
duke
parents:
diff changeset
65 JvmtiTagHashmapEntry* _next; // next on the list
a61af66fc99e Initial load
duke
parents:
diff changeset
66
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
67 inline void init(oop object, jlong tag) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _object = object;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 _tag = tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // constructor
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
74 JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // accessor methods
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
79 inline oop object() const { return _object; }
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
80 inline oop* object_addr() { return &_object; }
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
81 inline jlong tag() const { return _tag; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 inline void set_tag(jlong tag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 assert(tag != 0, "can't be zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 _tag = tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 inline JvmtiTagHashmapEntry* next() const { return _next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 };
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // JvmtiTagHashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
94 //
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // A hashmap is essentially a table of pointers to entries. Entries
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // are hashed to a location, or position in the table, and then
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // chained from that location. The "key" for hashing is address of
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
98 // the object, or oop. The "value" is the tag value.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
99 //
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // A hashmap maintains a count of the number entries in the hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // and resizes if the number of entries exceeds a given threshold.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // The threshold is specified as a percentage of the size - for
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // example a threshold of 0.75 will trigger the hashmap to resize
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // if the number of entries is >75% of table size.
a61af66fc99e Initial load
duke
parents:
diff changeset
105 //
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // A hashmap provides functions for adding, removing, and finding
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // entries. It also provides a function to iterate over all entries
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // in the hashmap.
a61af66fc99e Initial load
duke
parents:
diff changeset
109
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
110 class JvmtiTagHashmap : public CHeapObj<mtInternal> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
111 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
112 friend class JvmtiTagMap;
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 small_trace_threshold = 10000, // threshold for tracing
a61af66fc99e Initial load
duke
parents:
diff changeset
116 medium_trace_threshold = 100000,
a61af66fc99e Initial load
duke
parents:
diff changeset
117 large_trace_threshold = 1000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
118 initial_trace_threshold = small_trace_threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
119 };
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 static int _sizes[]; // array of possible hashmap sizes
a61af66fc99e Initial load
duke
parents:
diff changeset
122 int _size; // actual size of the table
a61af66fc99e Initial load
duke
parents:
diff changeset
123 int _size_index; // index into size table
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 int _entry_count; // number of entries in the hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 float _load_factor; // load factor as a % of the size
a61af66fc99e Initial load
duke
parents:
diff changeset
128 int _resize_threshold; // computed threshold to trigger resizing.
a61af66fc99e Initial load
duke
parents:
diff changeset
129 bool _resizing_enabled; // indicates if hashmap can resize
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 int _trace_threshold; // threshold for trace messages
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 JvmtiTagHashmapEntry** _table; // the table of entries.
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // private accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
136 int resize_threshold() const { return _resize_threshold; }
a61af66fc99e Initial load
duke
parents:
diff changeset
137 int trace_threshold() const { return _trace_threshold; }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // initialize the hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
140 void init(int size_index=0, float load_factor=4.0f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 int initial_size = _sizes[size_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
142 _size_index = size_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 _size = initial_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 _entry_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 if (TraceJVMTIObjectTagging) {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _trace_threshold = initial_trace_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 _trace_threshold = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
150 _load_factor = load_factor;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 _resize_threshold = (int)(_load_factor * _size);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 _resizing_enabled = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*);
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
154 _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (_table == NULL) {
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 8001
diff changeset
156 vm_exit_out_of_memory(s, OOM_MALLOC_ERROR,
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 8001
diff changeset
157 "unable to allocate initial hashtable for jvmti object tags");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 for (int i=0; i<initial_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 _table[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // hash a given key (oop) with the specified size
a61af66fc99e Initial load
duke
parents:
diff changeset
165 static unsigned int hash(oop key, int size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // shift right to get better distribution (as these bits will be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // with aligned addresses)
a61af66fc99e Initial load
duke
parents:
diff changeset
168 unsigned int addr = (unsigned int)((intptr_t)key);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
170 return (addr >> 3) % size;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return (addr >> 2) % size;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // hash a given key (oop)
a61af66fc99e Initial load
duke
parents:
diff changeset
177 unsigned int hash(oop key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 return hash(key, _size);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // resize the hashmap - allocates a large table and re-hashes
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // all entries into the new table.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 void resize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 int new_size_index = _size_index+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 int new_size = _sizes[new_size_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (new_size < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // hashmap already at maximum capacity
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // allocate new table
a61af66fc99e Initial load
duke
parents:
diff changeset
192 size_t s = new_size * sizeof(JvmtiTagHashmapEntry*);
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
193 JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (new_table == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 warning("unable to allocate larger hashtable for jvmti object tags");
a61af66fc99e Initial load
duke
parents:
diff changeset
196 set_resizing_enabled(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // initialize new table
a61af66fc99e Initial load
duke
parents:
diff changeset
201 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 for (i=0; i<new_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 new_table[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // rehash all entries into the new table
a61af66fc99e Initial load
duke
parents:
diff changeset
207 for (i=0; i<_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 JvmtiTagHashmapEntry* entry = _table[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
209 while (entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 JvmtiTagHashmapEntry* next = entry->next();
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
211 oop key = entry->object();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
212 assert(key != NULL, "jni weak reference cleared!!");
a61af66fc99e Initial load
duke
parents:
diff changeset
213 unsigned int h = hash(key, new_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 JvmtiTagHashmapEntry* anchor = new_table[h];
a61af66fc99e Initial load
duke
parents:
diff changeset
215 if (anchor == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 new_table[h] = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 entry->set_next(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 entry->set_next(anchor);
a61af66fc99e Initial load
duke
parents:
diff changeset
220 new_table[h] = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222 entry = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // free old table and update settings.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 os::free((void*)_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _table = new_table;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 _size_index = new_size_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 _size = new_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // compute new resize threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _resize_threshold = (int)(_load_factor * _size);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // internal remove function - remove an entry at a given position in the
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // table.
a61af66fc99e Initial load
duke
parents:
diff changeset
239 inline void remove(JvmtiTagHashmapEntry* prev, int pos, JvmtiTagHashmapEntry* entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 assert(pos >= 0 && pos < _size, "out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (prev == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 _table[pos] = entry->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
243 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 prev->set_next(entry->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 assert(_entry_count > 0, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
247 _entry_count--;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // resizing switch
a61af66fc99e Initial load
duke
parents:
diff changeset
251 bool is_resizing_enabled() const { return _resizing_enabled; }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 void set_resizing_enabled(bool enable) { _resizing_enabled = enable; }
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void print_memory_usage();
a61af66fc99e Initial load
duke
parents:
diff changeset
256 void compute_next_trace_threshold();
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // create a JvmtiTagHashmap of a preferred size and optionally a load factor.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // The preferred size is rounded down to an actual size.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 JvmtiTagHashmap(int size, float load_factor=0.0f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 int i=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 while (_sizes[i] < size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (_sizes[i] < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 assert(i > 0, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
267 i--;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // if a load factor is specified then use it, otherwise use default
a61af66fc99e Initial load
duke
parents:
diff changeset
274 if (load_factor > 0.01f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 init(i, load_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 init(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // create a JvmtiTagHashmap with default settings
a61af66fc99e Initial load
duke
parents:
diff changeset
282 JvmtiTagHashmap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 init();
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // release table when JvmtiTagHashmap destroyed
a61af66fc99e Initial load
duke
parents:
diff changeset
287 ~JvmtiTagHashmap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if (_table != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 os::free((void*)_table);
a61af66fc99e Initial load
duke
parents:
diff changeset
290 _table = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
295 int size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
296 JvmtiTagHashmapEntry** table() const { return _table; }
a61af66fc99e Initial load
duke
parents:
diff changeset
297 int entry_count() const { return _entry_count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // find an entry in the hashmap, returns NULL if not found.
a61af66fc99e Initial load
duke
parents:
diff changeset
300 inline JvmtiTagHashmapEntry* find(oop key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 unsigned int h = hash(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 JvmtiTagHashmapEntry* entry = _table[h];
a61af66fc99e Initial load
duke
parents:
diff changeset
303 while (entry != NULL) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
304 if (entry->object() == key) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
305 return entry;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 entry = entry->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
309 return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // add a new entry to hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
314 inline void add(oop key, JvmtiTagHashmapEntry* entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 assert(key != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
316 assert(find(key) == NULL, "duplicate detected");
a61af66fc99e Initial load
duke
parents:
diff changeset
317 unsigned int h = hash(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 JvmtiTagHashmapEntry* anchor = _table[h];
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (anchor == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 _table[h] = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 entry->set_next(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 entry->set_next(anchor);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 _table[h] = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 _entry_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (trace_threshold() > 0 && entry_count() >= trace_threshold()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 assert(TraceJVMTIObjectTagging, "should only get here when tracing");
a61af66fc99e Initial load
duke
parents:
diff changeset
330 print_memory_usage();
a61af66fc99e Initial load
duke
parents:
diff changeset
331 compute_next_trace_threshold();
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // if the number of entries exceed the threshold then resize
a61af66fc99e Initial load
duke
parents:
diff changeset
335 if (entry_count() > resize_threshold() && is_resizing_enabled()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 resize();
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // remove an entry with the given key.
a61af66fc99e Initial load
duke
parents:
diff changeset
341 inline JvmtiTagHashmapEntry* remove(oop key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 unsigned int h = hash(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 JvmtiTagHashmapEntry* entry = _table[h];
a61af66fc99e Initial load
duke
parents:
diff changeset
344 JvmtiTagHashmapEntry* prev = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 while (entry != NULL) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
346 if (key == entry->object()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
347 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349 prev = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
350 entry = entry->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if (entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 remove(prev, h, entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // iterate over all entries in the hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
359 void entry_iterate(JvmtiTagHashmapEntryClosure* closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 };
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // possible hashmap sizes - odd primes that roughly double in size.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // To avoid excessive resizing the odd primes from 4801-76831 and
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // 76831-307261 have been removed. The list must be terminated by -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
365 int JvmtiTagHashmap::_sizes[] = { 4801, 76831, 307261, 614563, 1228891,
a61af66fc99e Initial load
duke
parents:
diff changeset
366 2457733, 4915219, 9830479, 19660831, 39321619, 78643219, -1 };
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // A supporting class for iterating over all entries in Hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
370 class JvmtiTagHashmapEntryClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
372 virtual void do_entry(JvmtiTagHashmapEntry* entry) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 };
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // iterate over all entries in the hashmap
a61af66fc99e Initial load
duke
parents:
diff changeset
377 void JvmtiTagHashmap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
378 for (int i=0; i<_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 JvmtiTagHashmapEntry* entry = _table[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
380 JvmtiTagHashmapEntry* prev = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 while (entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // obtain the next entry before invoking do_entry - this is
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // necessary because do_entry may remove the entry from the
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // hashmap.
a61af66fc99e Initial load
duke
parents:
diff changeset
385 JvmtiTagHashmapEntry* next = entry->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
386 closure->do_entry(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
387 entry = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void JvmtiTagHashmap::print_memory_usage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 intptr_t p = (intptr_t)this;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 tty->print("[JvmtiTagHashmap @ " INTPTR_FORMAT, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // table + entries in KB
a61af66fc99e Initial load
duke
parents:
diff changeset
398 int hashmap_usage = (size()*sizeof(JvmtiTagHashmapEntry*) +
a61af66fc99e Initial load
duke
parents:
diff changeset
399 entry_count()*sizeof(JvmtiTagHashmapEntry))/K;
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 int weak_globals_usage = (int)(JNIHandles::weak_global_handle_memory_usage()/K);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 tty->print_cr(", %d entries (%d KB) <JNI weak globals: %d KB>]",
a61af66fc99e Initial load
duke
parents:
diff changeset
403 entry_count(), hashmap_usage, weak_globals_usage);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // compute threshold for the next trace message
a61af66fc99e Initial load
duke
parents:
diff changeset
407 void JvmtiTagHashmap::compute_next_trace_threshold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 if (trace_threshold() < medium_trace_threshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 _trace_threshold += small_trace_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 if (trace_threshold() < large_trace_threshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 _trace_threshold += medium_trace_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 _trace_threshold += large_trace_threshold;
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // create a JvmtiTagMap
a61af66fc99e Initial load
duke
parents:
diff changeset
420 JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) :
a61af66fc99e Initial load
duke
parents:
diff changeset
421 _env(env),
a61af66fc99e Initial load
duke
parents:
diff changeset
422 _lock(Mutex::nonleaf+2, "JvmtiTagMap._lock", false),
a61af66fc99e Initial load
duke
parents:
diff changeset
423 _free_entries(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
424 _free_entries_count(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
425 {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 assert(JvmtiThreadState_lock->is_locked(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
427 assert(((JvmtiEnvBase *)env)->tag_map() == NULL, "tag map already exists for environment");
a61af66fc99e Initial load
duke
parents:
diff changeset
428
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
429 _hashmap = new JvmtiTagHashmap();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // finally add us to the environment
a61af66fc99e Initial load
duke
parents:
diff changeset
432 ((JvmtiEnvBase *)env)->set_tag_map(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // destroy a JvmtiTagMap
a61af66fc99e Initial load
duke
parents:
diff changeset
437 JvmtiTagMap::~JvmtiTagMap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // no lock acquired as we assume the enclosing environment is
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // also being destroryed.
a61af66fc99e Initial load
duke
parents:
diff changeset
441 ((JvmtiEnvBase *)_env)->set_tag_map(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
442
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
443 JvmtiTagHashmapEntry** table = _hashmap->table();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
444 for (int j = 0; j < _hashmap->size(); j++) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
445 JvmtiTagHashmapEntry* entry = table[j];
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
446 while (entry != NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
447 JvmtiTagHashmapEntry* next = entry->next();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
448 delete entry;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
449 entry = next;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
453 // finally destroy the hashmap
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
454 delete _hashmap;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
455 _hashmap = NULL;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
456
0
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // remove any entries on the free list
a61af66fc99e Initial load
duke
parents:
diff changeset
458 JvmtiTagHashmapEntry* entry = _free_entries;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 while (entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 JvmtiTagHashmapEntry* next = entry->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
461 delete entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 entry = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
464 _free_entries = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // create a hashmap entry
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // - if there's an entry on the (per-environment) free list then this
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // is returned. Otherwise an new entry is allocated.
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
470 JvmtiTagHashmapEntry* JvmtiTagMap::create_entry(oop ref, jlong tag) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
471 assert(Thread::current()->is_VM_thread() || is_locked(), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
472 JvmtiTagHashmapEntry* entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if (_free_entries == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 entry = new JvmtiTagHashmapEntry(ref, tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 assert(_free_entries_count > 0, "mismatched _free_entries_count");
a61af66fc99e Initial load
duke
parents:
diff changeset
477 _free_entries_count--;
a61af66fc99e Initial load
duke
parents:
diff changeset
478 entry = _free_entries;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 _free_entries = entry->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
480 entry->init(ref, tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 return entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // destroy an entry by returning it to the free list
a61af66fc99e Initial load
duke
parents:
diff changeset
486 void JvmtiTagMap::destroy_entry(JvmtiTagHashmapEntry* entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 assert(SafepointSynchronize::is_at_safepoint() || is_locked(), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // limit the size of the free list
a61af66fc99e Initial load
duke
parents:
diff changeset
489 if (_free_entries_count >= max_free_entries) {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 delete entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 entry->set_next(_free_entries);
a61af66fc99e Initial load
duke
parents:
diff changeset
493 _free_entries = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
494 _free_entries_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // returns the tag map for the given environments. If the tag map
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // doesn't exist then it is created.
a61af66fc99e Initial load
duke
parents:
diff changeset
500 JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
501 JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->tag_map();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
502 if (tag_map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 MutexLocker mu(JvmtiThreadState_lock);
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
504 tag_map = ((JvmtiEnvBase*)env)->tag_map();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (tag_map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 tag_map = new JvmtiTagMap(env);
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511 return tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // iterate over all entries in the tag map.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 void JvmtiTagMap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
516 hashmap()->entry_iterate(closure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // returns true if the hashmaps are empty
a61af66fc99e Initial load
duke
parents:
diff changeset
520 bool JvmtiTagMap::is_empty() {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 assert(SafepointSynchronize::is_at_safepoint() || is_locked(), "checking");
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
522 return hashmap()->entry_count() == 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // Return the tag value for an object, or 0 if the object is
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // not tagged
a61af66fc99e Initial load
duke
parents:
diff changeset
528 //
a61af66fc99e Initial load
duke
parents:
diff changeset
529 static inline jlong tag_for(JvmtiTagMap* tag_map, oop o) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
530 JvmtiTagHashmapEntry* entry = tag_map->hashmap()->find(o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (entry == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 return entry->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // A CallbackWrapper is a support class for querying and tagging an object
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // around a callback to a profiler. The constructor does pre-callback
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // work to get the tag value, klass tag value, ... and the destructor
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // does the post-callback work of tagging or untagging the object.
a61af66fc99e Initial load
duke
parents:
diff changeset
543 //
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // CallbackWrapper wrapper(tag_map, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
546 //
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // (*callback)(wrapper.klass_tag(), wrapper.obj_size(), wrapper.obj_tag_p(), ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
548 //
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // } // wrapper goes out of scope here which results in the destructor
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // checking to see if the object has been tagged, untagged, or the
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // tag value has changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
552 //
a61af66fc99e Initial load
duke
parents:
diff changeset
553 class CallbackWrapper : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
555 JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 JvmtiTagHashmap* _hashmap;
a61af66fc99e Initial load
duke
parents:
diff changeset
557 JvmtiTagHashmapEntry* _entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
558 oop _o;
a61af66fc99e Initial load
duke
parents:
diff changeset
559 jlong _obj_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 jlong _obj_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
561 jlong _klass_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
564 JvmtiTagMap* tag_map() const { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // invoked post-callback to tag, untag, or update the tag of an object
a61af66fc99e Initial load
duke
parents:
diff changeset
567 void inline post_callback_tag_update(oop o, JvmtiTagHashmap* hashmap,
a61af66fc99e Initial load
duke
parents:
diff changeset
568 JvmtiTagHashmapEntry* entry, jlong obj_tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
570 CallbackWrapper(JvmtiTagMap* tag_map, oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 assert(Thread::current()->is_VM_thread() || tag_map->is_locked(),
a61af66fc99e Initial load
duke
parents:
diff changeset
572 "MT unsafe or must be VM thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
573
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
574 // object to tag
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
575 _o = o;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // object size
6171
588f559105c1 7178846: IterateThroughHeap: heap_iteration_callback passes a negative size
sla
parents: 4929
diff changeset
578 _obj_size = (jlong)_o->size() * wordSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // record the context
a61af66fc99e Initial load
duke
parents:
diff changeset
581 _tag_map = tag_map;
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
582 _hashmap = tag_map->hashmap();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
583 _entry = _hashmap->find(_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // get object tag
a61af66fc99e Initial load
duke
parents:
diff changeset
586 _obj_tag = (_entry == NULL) ? 0 : _entry->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // get the class and the class's tag value
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
589 assert(SystemDictionary::Class_klass()->oop_is_instanceMirror(), "Is not?");
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
590
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
591 _klass_tag = tag_for(tag_map, _o->klass()->java_mirror());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 ~CallbackWrapper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 post_callback_tag_update(_o, _hashmap, _entry, _obj_tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 }
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 inline jlong* obj_tag_p() { return &_obj_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
599 inline jlong obj_size() const { return _obj_size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 inline jlong obj_tag() const { return _obj_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
601 inline jlong klass_tag() const { return _klass_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
602 };
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // callback post-callback to tag, untag, or update the tag of an object
a61af66fc99e Initial load
duke
parents:
diff changeset
607 void inline CallbackWrapper::post_callback_tag_update(oop o,
a61af66fc99e Initial load
duke
parents:
diff changeset
608 JvmtiTagHashmap* hashmap,
a61af66fc99e Initial load
duke
parents:
diff changeset
609 JvmtiTagHashmapEntry* entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
610 jlong obj_tag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 if (entry == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if (obj_tag != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // callback has tagged the object
a61af66fc99e Initial load
duke
parents:
diff changeset
614 assert(Thread::current()->is_VM_thread(), "must be VMThread");
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
615 entry = tag_map()->create_entry(o, obj_tag);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
616 hashmap->add(o, entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
618 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // object was previously tagged - the callback may have untagged
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // the object or changed the tag value
a61af66fc99e Initial load
duke
parents:
diff changeset
621 if (obj_tag == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 JvmtiTagHashmapEntry* entry_removed = hashmap->remove(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
624 assert(entry_removed == entry, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
625 tag_map()->destroy_entry(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 if (obj_tag != entry->tag()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 entry->set_tag(obj_tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // An extended CallbackWrapper used when reporting an object reference
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // to the agent.
a61af66fc99e Initial load
duke
parents:
diff changeset
637 //
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // TwoOopCallbackWrapper wrapper(tag_map, referrer, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 //
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // (*callback)(wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // wrapper.obj_tag_p()
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // wrapper.referrer_tag_p(), ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
645 //
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // } // wrapper goes out of scope here which results in the destructor
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // checking to see if the referrer object has been tagged, untagged,
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // or the tag value has changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
649 //
a61af66fc99e Initial load
duke
parents:
diff changeset
650 class TwoOopCallbackWrapper : public CallbackWrapper {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
652 bool _is_reference_to_self;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 JvmtiTagHashmap* _referrer_hashmap;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 JvmtiTagHashmapEntry* _referrer_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
655 oop _referrer;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 jlong _referrer_obj_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 jlong _referrer_klass_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 jlong* _referrer_tag_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 bool is_reference_to_self() const { return _is_reference_to_self; }
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
663 TwoOopCallbackWrapper(JvmtiTagMap* tag_map, oop referrer, oop o) :
a61af66fc99e Initial load
duke
parents:
diff changeset
664 CallbackWrapper(tag_map, o)
a61af66fc99e Initial load
duke
parents:
diff changeset
665 {
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // self reference needs to be handled in a special way
a61af66fc99e Initial load
duke
parents:
diff changeset
667 _is_reference_to_self = (referrer == o);
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if (_is_reference_to_self) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 _referrer_klass_tag = klass_tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
671 _referrer_tag_p = obj_tag_p();
a61af66fc99e Initial load
duke
parents:
diff changeset
672 } else {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
673 _referrer = referrer;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // record the context
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
675 _referrer_hashmap = tag_map->hashmap();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
676 _referrer_entry = _referrer_hashmap->find(_referrer);
a61af66fc99e Initial load
duke
parents:
diff changeset
677
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // get object tag
a61af66fc99e Initial load
duke
parents:
diff changeset
679 _referrer_obj_tag = (_referrer_entry == NULL) ? 0 : _referrer_entry->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
680 _referrer_tag_p = &_referrer_obj_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // get referrer class tag.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
683 _referrer_klass_tag = tag_for(tag_map, _referrer->klass()->java_mirror());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 ~TwoOopCallbackWrapper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 if (!is_reference_to_self()){
a61af66fc99e Initial load
duke
parents:
diff changeset
689 post_callback_tag_update(_referrer,
a61af66fc99e Initial load
duke
parents:
diff changeset
690 _referrer_hashmap,
a61af66fc99e Initial load
duke
parents:
diff changeset
691 _referrer_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
692 _referrer_obj_tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // address of referrer tag
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // (for a self reference this will return the same thing as obj_tag_p())
a61af66fc99e Initial load
duke
parents:
diff changeset
698 inline jlong* referrer_tag_p() { return _referrer_tag_p; }
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // referrer's class tag
a61af66fc99e Initial load
duke
parents:
diff changeset
701 inline jlong referrer_klass_tag() { return _referrer_klass_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
702 };
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // tag an object
a61af66fc99e Initial load
duke
parents:
diff changeset
705 //
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // This function is performance critical. If many threads attempt to tag objects
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // around the same time then it's possible that the Mutex associated with the
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
708 // tag map will be a hot lock.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
709 void JvmtiTagMap::set_tag(jobject object, jlong tag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
710 MutexLocker ml(lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 // resolve the object
a61af66fc99e Initial load
duke
parents:
diff changeset
713 oop o = JNIHandles::resolve_non_null(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // see if the object is already tagged
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
716 JvmtiTagHashmap* hashmap = _hashmap;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
717 JvmtiTagHashmapEntry* entry = hashmap->find(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // if the object is not already tagged then we tag it
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (entry == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (tag != 0) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
722 entry = create_entry(o, tag);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
723 hashmap->add(o, entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
724 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // no-op
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // if the object is already tagged then we either update
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // the tag (if a new tag value has been provided)
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // or remove the object if the new tag value is 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
731 if (tag == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 hashmap->remove(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 destroy_entry(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
735 entry->set_tag(tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // get the tag for an object
a61af66fc99e Initial load
duke
parents:
diff changeset
741 jlong JvmtiTagMap::get_tag(jobject object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 MutexLocker ml(lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // resolve the object
a61af66fc99e Initial load
duke
parents:
diff changeset
745 oop o = JNIHandles::resolve_non_null(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
746
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
747 return tag_for(this, o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // Helper class used to describe the static or instance fields of a class.
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // For each field it holds the field index (as defined by the JVMTI specification),
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // the field type, and the offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
754
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
755 class ClassFieldDescriptor: public CHeapObj<mtInternal> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
756 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
757 int _field_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 int _field_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 char _field_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
761 ClassFieldDescriptor(int index, char type, int offset) :
a61af66fc99e Initial load
duke
parents:
diff changeset
762 _field_index(index), _field_type(type), _field_offset(offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764 int field_index() const { return _field_index; }
a61af66fc99e Initial load
duke
parents:
diff changeset
765 char field_type() const { return _field_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
766 int field_offset() const { return _field_offset; }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 };
a61af66fc99e Initial load
duke
parents:
diff changeset
768
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
769 class ClassFieldMap: public CHeapObj<mtInternal> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
770 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
771 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 initial_field_count = 5
a61af66fc99e Initial load
duke
parents:
diff changeset
773 };
a61af66fc99e Initial load
duke
parents:
diff changeset
774
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // list of field descriptors
a61af66fc99e Initial load
duke
parents:
diff changeset
776 GrowableArray<ClassFieldDescriptor*>* _fields;
a61af66fc99e Initial load
duke
parents:
diff changeset
777
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
779 ClassFieldMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
780
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // add a field
a61af66fc99e Initial load
duke
parents:
diff changeset
782 void add(int index, char type, int offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // returns the field count for the given class
a61af66fc99e Initial load
duke
parents:
diff changeset
785 static int compute_field_count(instanceKlassHandle ikh);
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
788 ~ClassFieldMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // access
a61af66fc99e Initial load
duke
parents:
diff changeset
791 int field_count() { return _fields->length(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
792 ClassFieldDescriptor* field_at(int i) { return _fields->at(i); }
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // functions to create maps of static or instance fields
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
795 static ClassFieldMap* create_map_of_static_fields(Klass* k);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
796 static ClassFieldMap* create_map_of_instance_fields(oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 };
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 ClassFieldMap::ClassFieldMap() {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
800 _fields = new (ResourceObj::C_HEAP, mtInternal)
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
801 GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803
a61af66fc99e Initial load
duke
parents:
diff changeset
804 ClassFieldMap::~ClassFieldMap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
805 for (int i=0; i<_fields->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 delete _fields->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
808 delete _fields;
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 void ClassFieldMap::add(int index, char type, int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
813 _fields->append(field);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // Returns a heap allocated ClassFieldMap to describe the static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // of the given class.
a61af66fc99e Initial load
duke
parents:
diff changeset
818 //
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
819 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
820 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
821 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // create the field map
a61af66fc99e Initial load
duke
parents:
diff changeset
824 ClassFieldMap* field_map = new ClassFieldMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 FilteredFieldStream f(ikh, false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
827 int max_field_index = f.field_count()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 int index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
830 for (FilteredFieldStream fld(ikh, true, true); !fld.eos(); fld.next(), index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // ignore instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
832 if (!fld.access_flags().is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
833 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835 field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
837 return field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
839
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // Returns a heap allocated ClassFieldMap to describe the instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // of the given class. All instance fields are included (this means public
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // and private fields declared in superclasses and superinterfaces too).
a61af66fc99e Initial load
duke
parents:
diff changeset
843 //
a61af66fc99e Initial load
duke
parents:
diff changeset
844 ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
846 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), obj->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // create the field map
a61af66fc99e Initial load
duke
parents:
diff changeset
849 ClassFieldMap* field_map = new ClassFieldMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
850
a61af66fc99e Initial load
duke
parents:
diff changeset
851 FilteredFieldStream f(ikh, false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 int max_field_index = f.field_count()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 int index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
856 for (FilteredFieldStream fld(ikh, false, false); !fld.eos(); fld.next(), index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // ignore static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
858 if (fld.access_flags().is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861 field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 return field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // Helper class used to cache a ClassFileMap for the instance fields of
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
868 // a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during
0
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // heap iteration and avoid creating a field map for each object in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // (only need to create the map when the first instance of a class is encountered).
a61af66fc99e Initial load
duke
parents:
diff changeset
871 //
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
872 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
873 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
874 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
875 initial_class_count = 200
a61af66fc99e Initial load
duke
parents:
diff changeset
876 };
a61af66fc99e Initial load
duke
parents:
diff changeset
877 ClassFieldMap* _field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 ClassFieldMap* field_map() const { return _field_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 JvmtiCachedClassFieldMap(ClassFieldMap* field_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
882 ~JvmtiCachedClassFieldMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
883
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
884 static GrowableArray<InstanceKlass*>* _class_list;
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
885 static void add_to_class_list(InstanceKlass* ik);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
886
a61af66fc99e Initial load
duke
parents:
diff changeset
887 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // returns the field map for a given object (returning map cached
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
889 // by InstanceKlass if possible
0
a61af66fc99e Initial load
duke
parents:
diff changeset
890 static ClassFieldMap* get_map_of_instance_fields(oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // removes the field map from all instanceKlasses - should be
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // called before VM operation completes
a61af66fc99e Initial load
duke
parents:
diff changeset
894 static void clear_cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
895
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // returns the number of ClassFieldMap cached by instanceKlasses
a61af66fc99e Initial load
duke
parents:
diff changeset
897 static int cached_field_map_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
898 };
a61af66fc99e Initial load
duke
parents:
diff changeset
899
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
900 GrowableArray<InstanceKlass*>* JvmtiCachedClassFieldMap::_class_list;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 _field_map = field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 JvmtiCachedClassFieldMap::~JvmtiCachedClassFieldMap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (_field_map != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 delete _field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // Marker class to ensure that the class file map cache is only used in a defined
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // scope.
a61af66fc99e Initial load
duke
parents:
diff changeset
914 class ClassFieldMapCacheMark : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
916 static bool _is_active;
a61af66fc99e Initial load
duke
parents:
diff changeset
917 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
918 ClassFieldMapCacheMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 assert(Thread::current()->is_VM_thread(), "must be VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
920 assert(JvmtiCachedClassFieldMap::cached_field_map_count() == 0, "cache not empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
921 assert(!_is_active, "ClassFieldMapCacheMark cannot be nested");
a61af66fc99e Initial load
duke
parents:
diff changeset
922 _is_active = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924 ~ClassFieldMapCacheMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 JvmtiCachedClassFieldMap::clear_cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
926 _is_active = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
928 static bool is_active() { return _is_active; }
a61af66fc99e Initial load
duke
parents:
diff changeset
929 };
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931 bool ClassFieldMapCacheMark::_is_active;
a61af66fc99e Initial load
duke
parents:
diff changeset
932
a61af66fc99e Initial load
duke
parents:
diff changeset
933
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
934 // record that the given InstanceKlass is caching a field map
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
935 void JvmtiCachedClassFieldMap::add_to_class_list(InstanceKlass* ik) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (_class_list == NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
937 _class_list = new (ResourceObj::C_HEAP, mtInternal)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
938 GrowableArray<InstanceKlass*>(initial_class_count, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940 _class_list->push(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // returns the instance field map for the given object
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
944 // (returns field map cached by the InstanceKlass if possible)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
945 ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 assert(Thread::current()->is_VM_thread(), "must be VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
947 assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active");
a61af66fc99e Initial load
duke
parents:
diff changeset
948
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
949 Klass* k = obj->klass();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
950 InstanceKlass* ik = InstanceKlass::cast(k);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 // return cached map if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
953 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if (cached_map != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
955 assert(cached_map->field_map() != NULL, "missing field list");
a61af66fc99e Initial load
duke
parents:
diff changeset
956 return cached_map->field_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
957 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 ClassFieldMap* field_map = ClassFieldMap::create_map_of_instance_fields(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 cached_map = new JvmtiCachedClassFieldMap(field_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
960 ik->set_jvmti_cached_class_field_map(cached_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 add_to_class_list(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
962 return field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // remove the fields maps cached from all instanceKlasses
a61af66fc99e Initial load
duke
parents:
diff changeset
967 void JvmtiCachedClassFieldMap::clear_cache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
968 assert(Thread::current()->is_VM_thread(), "must be VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
969 if (_class_list != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
970 for (int i = 0; i < _class_list->length(); i++) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
971 InstanceKlass* ik = _class_list->at(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
972 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
973 assert(cached_map != NULL, "should not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
974 ik->set_jvmti_cached_class_field_map(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
975 delete cached_map; // deletes the encapsulated field map
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977 delete _class_list;
a61af66fc99e Initial load
duke
parents:
diff changeset
978 _class_list = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
981
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // returns the number of ClassFieldMap cached by instanceKlasses
a61af66fc99e Initial load
duke
parents:
diff changeset
983 int JvmtiCachedClassFieldMap::cached_field_map_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
984 return (_class_list == NULL) ? 0 : _class_list->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // helper function to indicate if an object is filtered by its tag or class tag
a61af66fc99e Initial load
duke
parents:
diff changeset
988 static inline bool is_filtered_by_heap_filter(jlong obj_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
989 jlong klass_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
990 int heap_filter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // apply the heap filter
a61af66fc99e Initial load
duke
parents:
diff changeset
992 if (obj_tag != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // filter out tagged objects
a61af66fc99e Initial load
duke
parents:
diff changeset
994 if (heap_filter & JVMTI_HEAP_FILTER_TAGGED) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // filter out untagged objects
a61af66fc99e Initial load
duke
parents:
diff changeset
997 if (heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
999 if (klass_tag != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // filter out objects with tagged classes
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 if (heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 // filter out objects with untagged classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 if (heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // helper function to indicate if an object is filtered by a klass filter
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 static inline bool is_filtered_by_klass_filter(oop obj, KlassHandle klass_filter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 if (!klass_filter.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 if (obj->klass() != klass_filter()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // helper function to tell if a field is a primitive field or not
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 static inline bool is_primitive_field_type(char type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 return (type != 'L' && type != '[');
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1023
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // helper function to copy the value from location addr to jvalue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 static inline void copy_to_jvalue(jvalue *v, address addr, jvmtiPrimitiveType value_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 switch (value_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 case JVMTI_PRIMITIVE_TYPE_BOOLEAN : { v->z = *(jboolean*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 case JVMTI_PRIMITIVE_TYPE_BYTE : { v->b = *(jbyte*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 case JVMTI_PRIMITIVE_TYPE_CHAR : { v->c = *(jchar*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 case JVMTI_PRIMITIVE_TYPE_SHORT : { v->s = *(jshort*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 case JVMTI_PRIMITIVE_TYPE_INT : { v->i = *(jint*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 case JVMTI_PRIMITIVE_TYPE_LONG : { v->j = *(jlong*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 case JVMTI_PRIMITIVE_TYPE_FLOAT : { v->f = *(jfloat*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 case JVMTI_PRIMITIVE_TYPE_DOUBLE : { v->d = *(jdouble*)addr; break; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // helper function to invoke string primitive value callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // returns visit control flags
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 static jint invoke_string_value_callback(jvmtiStringPrimitiveValueCallback cb,
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 CallbackWrapper* wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 oop str,
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
1046 assert(str->klass() == SystemDictionary::String_klass(), "not a string");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1047
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // get the string value and length
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // (string value may be offset from the base)
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 int s_len = java_lang_String::length(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 typeArrayOop s_value = java_lang_String::value(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 int s_offset = java_lang_String::offset(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 jchar* value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 if (s_len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 value = s_value->char_at_addr(s_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 value = (jchar*) s_value->base(T_CHAR);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 return (*cb)(wrapper->klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 wrapper->obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 wrapper->obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 (jint)s_len,
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // helper function to invoke string primitive value callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 // returns visit control flags
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 static jint invoke_array_primitive_value_callback(jvmtiArrayPrimitiveValueCallback cb,
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 CallbackWrapper* wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 assert(obj->is_typeArray(), "not a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // get base address of first element
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 typeArrayOop array = typeArrayOop(obj);
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6738
diff changeset
1080 BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 void* elements = array->base(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // jvmtiPrimitiveType is defined so this mapping is always correct
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 jvmtiPrimitiveType elem_type = (jvmtiPrimitiveType)type2char(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1085
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 return (*cb)(wrapper->klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 wrapper->obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 wrapper->obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 (jint)array->length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 elem_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 elements,
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1094
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // helper function to invoke the primitive field callback for all static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // of a given class
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 static jint invoke_primitive_field_callback_for_static_fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 (CallbackWrapper* wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 jvmtiPrimitiveFieldCallback cb,
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // for static fields only the index will be set
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 static jvmtiHeapReferenceInfo reference_info = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
1106 assert(obj->klass() == SystemDictionary::Class_klass(), "not a class");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 if (java_lang_Class::is_primitive(obj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 }
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1110 Klass* klass = java_lang_Class::as_Klass(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // ignore classes for object and type arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 if (!klass->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // ignore classes which aren't linked yet
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1118 InstanceKlass* ik = InstanceKlass::cast(klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 if (!ik->is_linked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 // get the field map
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1124 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // invoke the callback for each static primitive field
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 for (int i=0; i<field_map->field_count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 ClassFieldDescriptor* field = field_map->field_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // ignore non-primitive fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 char type = field->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 if (!is_primitive_field_type(type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // one-to-one mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // get offset and field value
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 int offset = field->field_offset();
6871
045cb62046a7 7093328: JVMTI: jvmtiPrimitiveFieldCallback always report 0's for static primitives
rbackman
parents: 6856
diff changeset
1140 address addr = (address)klass->java_mirror() + offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 jvalue value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 copy_to_jvalue(&value, addr, value_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // field index
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 reference_info.field.index = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 jint res = (*cb)(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 &reference_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 wrapper->klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 wrapper->obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 value_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // helper function to invoke the primitive field callback for all instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // of a given object
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 static jint invoke_primitive_field_callback_for_instance_fields(
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 CallbackWrapper* wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 jvmtiPrimitiveFieldCallback cb,
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // for instance fields only the index will be set
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 static jvmtiHeapReferenceInfo reference_info = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1175
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // get the map of the instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 ClassFieldMap* fields = JvmtiCachedClassFieldMap::get_map_of_instance_fields(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // invoke the callback for each instance primitive field
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 for (int i=0; i<fields->field_count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 ClassFieldDescriptor* field = fields->field_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 // ignore non-primitive fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 char type = field->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 if (!is_primitive_field_type(type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // one-to-one mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // get offset and field value
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 int offset = field->field_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 address addr = (address)obj + offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 jvalue value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 copy_to_jvalue(&value, addr, value_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1196
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // field index
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 reference_info.field.index = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 jint res = (*cb)(JVMTI_HEAP_REFERENCE_FIELD,
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 &reference_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 wrapper->klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 wrapper->obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 value_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // VM operation to iterate over all objects in the heap (both reachable
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 // and unreachable)
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 class VM_HeapIterateOperation: public VM_Operation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 ObjectClosure* _blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 VMOp_Type type() const { return VMOp_HeapIterateOperation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 void doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // allows class files maps to be cached during iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 ClassFieldMapCacheMark cm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // make sure that heap is parsable (fills TLABs with filler objects)
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // Verify heap before iteration - if the heap gets corrupted then
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // JVMTI's IterateOverHeap will crash.
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if (VerifyBeforeIteration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 Universe::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // do the iteration
517
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 356
diff changeset
1239 // If this operation encounters a bad object when using CMS,
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 356
diff changeset
1240 // consider using safe_object_iterate() which avoids perm gen
e9be0e04635a 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 356
diff changeset
1241 // objects that may contain bad references.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 Universe::heap()->object_iterate(_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // An ObjectClosure used to support the deprecated IterateOverHeap and
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // IterateOverInstancesOfClass functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 class IterateOverHeapObjectClosure: public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 KlassHandle _klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 jvmtiHeapObjectFilter _object_filter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 jvmtiHeapObjectCallback _heap_object_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 const void* _user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1257
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 JvmtiTagMap* tag_map() const { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 jvmtiHeapObjectFilter object_filter() const { return _object_filter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 jvmtiHeapObjectCallback object_callback() const { return _heap_object_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 KlassHandle klass() const { return _klass; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 const void* user_data() const { return _user_data; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // indicates if iteration has been aborted
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 bool _iteration_aborted;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 bool is_iteration_aborted() const { return _iteration_aborted; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 void set_iteration_aborted(bool aborted) { _iteration_aborted = aborted; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 IterateOverHeapObjectClosure(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 KlassHandle klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 jvmtiHeapObjectFilter object_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 jvmtiHeapObjectCallback heap_object_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 const void* user_data) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 _tag_map(tag_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 _klass(klass),
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 _object_filter(object_filter),
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 _heap_object_callback(heap_object_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 _user_data(user_data),
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 _iteration_aborted(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 void do_object(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1287
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // invoked for each object in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 void IterateOverHeapObjectClosure::do_object(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // check if iteration has been halted
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 if (is_iteration_aborted()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // ignore any objects that aren't visible to profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 if (!ServiceUtil::visible_oop(o)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1295
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // instanceof check when filtering by klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 if (!klass().is_null() && !o->is_a(klass()())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // prepare for the calllback
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 CallbackWrapper wrapper(tag_map(), o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // if the object is tagged and we're only interested in untagged objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // then don't invoke the callback. Similiarly, if the object is untagged
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // and we're only interested in tagged objects we skip the callback.
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 if (wrapper.obj_tag() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1311
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // invoke the agent's callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 if (control == JVMTI_ITERATION_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 set_iteration_aborted(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // An ObjectClosure used to support the IterateThroughHeap function
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 class IterateThroughHeapObjectClosure: public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 KlassHandle _klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 int _heap_filter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 const jvmtiHeapCallbacks* _callbacks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 const void* _user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // accessor functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 JvmtiTagMap* tag_map() const { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 int heap_filter() const { return _heap_filter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 const jvmtiHeapCallbacks* callbacks() const { return _callbacks; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 KlassHandle klass() const { return _klass; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 const void* user_data() const { return _user_data; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // indicates if the iteration has been aborted
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 bool _iteration_aborted;
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 bool is_iteration_aborted() const { return _iteration_aborted; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // used to check the visit control flags. If the abort flag is set
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // then we set the iteration aborted flag so that the iteration completes
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // without processing any further objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 bool check_flags_for_abort(jint flags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 bool is_abort = (flags & JVMTI_VISIT_ABORT) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if (is_abort) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 _iteration_aborted = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 return is_abort;
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1352
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 IterateThroughHeapObjectClosure(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 KlassHandle klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 int heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 const jvmtiHeapCallbacks* heap_callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 const void* user_data) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 _tag_map(tag_map),
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 _klass(klass),
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 _heap_filter(heap_filter),
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 _callbacks(heap_callbacks),
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 _user_data(user_data),
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 _iteration_aborted(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 void do_object(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1370
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // invoked for each object in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 void IterateThroughHeapObjectClosure::do_object(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // check if iteration has been halted
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 if (is_iteration_aborted()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // ignore any objects that aren't visible to profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 if (!ServiceUtil::visible_oop(obj)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1378
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 if (is_filtered_by_klass_filter(obj, klass())) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1381
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // prepare for callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1384
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // check if filtered by the heap filter
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 if (is_filtered_by_heap_filter(wrapper.obj_tag(), wrapper.klass_tag(), heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1389
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 bool is_array = obj->is_array();
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 int len = is_array ? arrayOop(obj)->length() : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1393
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // invoke the object callback (if callback is provided)
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 if (callbacks()->heap_iteration_callback != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 jvmtiHeapIterationCallback cb = callbacks()->heap_iteration_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 jint res = (*cb)(wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 (jint)len,
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 if (check_flags_for_abort(res)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 // for objects and classes we report primitive fields if callback provided
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 if (callbacks()->primitive_field_callback != NULL && obj->is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 jint res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 jvmtiPrimitiveFieldCallback cb = callbacks()->primitive_field_callback;
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
1409 if (obj->klass() == SystemDictionary::Class_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 res = invoke_primitive_field_callback_for_static_fields(&wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 cb,
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 res = invoke_primitive_field_callback_for_instance_fields(&wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 cb,
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 if (check_flags_for_abort(res)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1422
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // string callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 if (!is_array &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 callbacks()->string_primitive_value_callback != NULL &&
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
1426 obj->klass() == SystemDictionary::String_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 jint res = invoke_string_value_callback(
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 callbacks()->string_primitive_value_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 &wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 (void*)user_data() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 if (check_flags_for_abort(res)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1434
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // array callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if (is_array &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 callbacks()->array_primitive_value_callback != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 obj->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 jint res = invoke_array_primitive_value_callback(
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 callbacks()->array_primitive_value_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 &wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 (void*)user_data() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 if (check_flags_for_abort(res)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1447
a61af66fc99e Initial load
duke
parents:
diff changeset
1448
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // Deprecated function to iterate over all objects in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 KlassHandle klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 jvmtiHeapObjectCallback heap_object_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 const void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 IterateOverHeapObjectClosure blk(this,
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 object_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 heap_object_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 VM_HeapIterateOperation op(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // Iterates over all objects in the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 void JvmtiTagMap::iterate_through_heap(jint heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 KlassHandle klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 const jvmtiHeapCallbacks* callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 const void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 IterateThroughHeapObjectClosure blk(this,
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 VM_HeapIterateOperation op(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1481
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // support class for get_objects_with_tags
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 JvmtiEnv* _env;
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 jlong* _tags;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 jint _tag_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1489
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 GrowableArray<jobject>* _object_results; // collected objects (JNI weak refs)
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 GrowableArray<uint64_t>* _tag_results; // collected tags
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 TagObjectCollector(JvmtiEnv* env, const jlong* tags, jint tag_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 _env = env;
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 _tags = (jlong*)tags;
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 _tag_count = tag_count;
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
1498 _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true);
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
1499 _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 ~TagObjectCollector() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 delete _object_results;
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 delete _tag_results;
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1506
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // for each tagged object check if the tag value matches
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 // - if it matches then we create a JNI local reference to the object
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 // and record the reference and tag value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 void do_entry(JvmtiTagHashmapEntry* entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 for (int i=0; i<_tag_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 if (_tags[i] == entry->tag()) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
1514 oop o = entry->object();
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1515 assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 jobject ref = JNIHandles::make_local(JavaThread::current(), o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 _object_results->append(ref);
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 _tag_results->append((uint64_t)entry->tag());
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // return the results from the collection
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 jvmtiError result(jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 jvmtiError error;
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 int count = _object_results->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 assert(count >= 0, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 // if object_result_ptr is not NULL then allocate the result and copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // in the object references.
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 if (object_result_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 error = _env->Allocate(count * sizeof(jobject), (unsigned char**)object_result_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 if (error != JVMTI_ERROR_NONE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 return error;
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 for (int i=0; i<count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 (*object_result_ptr)[i] = _object_results->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1541
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // if tag_result_ptr is not NULL then allocate the result and copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // in the tag values.
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 if (tag_result_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 error = _env->Allocate(count * sizeof(jlong), (unsigned char**)tag_result_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 if (error != JVMTI_ERROR_NONE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 if (object_result_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 _env->Deallocate((unsigned char*)object_result_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 return error;
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 for (int i=0; i<count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 (*tag_result_ptr)[i] = (jlong)_tag_results->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 *count_ptr = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 return JVMTI_ERROR_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1561
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // return the list of objects with the specified tags
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags,
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 TagObjectCollector collector(env(), tags, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 // iterate over all tagged objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 MutexLocker ml(lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 entry_iterate(&collector);
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 return collector.result(count_ptr, object_result_ptr, tag_result_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1574
a61af66fc99e Initial load
duke
parents:
diff changeset
1575
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // ObjectMarker is used to support the marking objects when walking the
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 // This implementation uses the existing mark bits in an object for
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 // marking. Objects that are marked must later have their headers restored.
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // As most objects are unlocked and don't have their identity hash computed
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // we don't have to save their headers. Instead we save the headers that
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // are "interesting". Later when the headers are restored this implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // restores all headers to their initial value and then restores the few
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // objects that had interesting headers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // Future work: This implementation currently uses growable arrays to save
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // the oop and header of interesting objects. As an optimization we could
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // use the same technique as the GC and make use of the unused area
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // between top() and end().
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1592
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 // An ObjectClosure used to restore the mark bits of an object
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 class RestoreMarksClosure : public ObjectClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 void do_object(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 if (o != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 markOop mark = o->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 if (mark->is_marked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 o->init_mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1605
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // ObjectMarker provides the mark and visited functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 class ObjectMarker : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // saved headers
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 static GrowableArray<oop>* _saved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 static GrowableArray<markOop>* _saved_mark_stack;
3815
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1612 static bool _needs_reset; // do we need to reset mark bits?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1613
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 static void init(); // initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 static void done(); // clean-up
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 static inline void mark(oop o); // mark an object
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 static inline bool visited(oop o); // check if object has been visited
3815
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1620
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1621 static inline bool needs_reset() { return _needs_reset; }
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1622 static inline void set_needs_reset(bool v) { _needs_reset = v; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1624
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
3815
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1627 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1628
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 // initialize ObjectMarker - prepares for object marking
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 void ObjectMarker::init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 assert(Thread::current()->is_VM_thread(), "must be VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // prepare heap for iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
1635
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // create stacks for interesting headers
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
1637 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true);
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
1638 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1639
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 BiasedLocking::preserve_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 // Object marking is done so restore object headers
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 void ObjectMarker::done() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // iterate over all objects and restore the mark bits to
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // their initial value
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 RestoreMarksClosure blk;
3815
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1650 if (needs_reset()) {
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1651 Universe::heap()->object_iterate(&blk);
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1652 } else {
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1653 // We don't need to reset mark bits on this call, but reset the
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1654 // flag to the default for the next call.
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1655 set_needs_reset(true);
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
1656 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1657
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // now restore the interesting headers
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 for (int i = 0; i < _saved_oop_stack->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 oop o = _saved_oop_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 markOop mark = _saved_mark_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 o->set_mark(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1664
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 BiasedLocking::restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // free the stacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 delete _saved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 delete _saved_mark_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 // mark an object
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 inline void ObjectMarker::mark(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 assert(Universe::heap()->is_in(o), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 assert(!o->mark()->is_marked(), "should only mark an object once");
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // object's mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 markOop mark = o->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
1681
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 if (mark->must_be_preserved(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 _saved_mark_stack->push(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 _saved_oop_stack->push(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // mark the object
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 o->set_mark(markOopDesc::prototype()->set_marked());
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // return true if object is marked
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 inline bool ObjectMarker::visited(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 return o->mark()->is_marked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1695
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // Stack allocated class to help ensure that ObjectMarker is used
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 // correctly. Constructor initializes ObjectMarker, destructor calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // ObjectMarker's done() function to restore object headers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 class ObjectMarkerController : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 ObjectMarkerController() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 ObjectMarker::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 ~ObjectMarkerController() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 ObjectMarker::done();
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1708
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // (not performance critical as only used for roots)
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 switch (kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER;
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER;
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1724
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // Base class for all heap walk contexts. The base class maintains a flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // to indicate if the context is valid or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 class HeapWalkContext VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 bool _valid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 HeapWalkContext(bool valid) { _valid = valid; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 void invalidate() { _valid = false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 bool is_valid() const { return _valid; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1735
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 // A basic heap walk context for the deprecated heap walking functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 // The context for a basic heap walk are the callbacks and fields used by
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // the referrer caching scheme.
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 class BasicHeapWalkContext: public HeapWalkContext {
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 jvmtiHeapRootCallback _heap_root_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 jvmtiStackReferenceCallback _stack_ref_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 jvmtiObjectReferenceCallback _object_ref_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 // used for caching
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 oop _last_referrer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 jlong _last_referrer_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
1748
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 BasicHeapWalkContext() : HeapWalkContext(false) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1751
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 BasicHeapWalkContext(jvmtiHeapRootCallback heap_root_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 jvmtiStackReferenceCallback stack_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 jvmtiObjectReferenceCallback object_ref_callback) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 HeapWalkContext(true),
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 _heap_root_callback(heap_root_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 _stack_ref_callback(stack_ref_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 _object_ref_callback(object_ref_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 _last_referrer(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 _last_referrer_tag(0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1762
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 jvmtiHeapRootCallback heap_root_callback() const { return _heap_root_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 jvmtiStackReferenceCallback stack_ref_callback() const { return _stack_ref_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 oop last_referrer() const { return _last_referrer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 void set_last_referrer(oop referrer) { _last_referrer = referrer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 jlong last_referrer_tag() const { return _last_referrer_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1773
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 // The advanced heap walk context for the FollowReferences functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // The context is the callbacks, and the fields used for filtering.
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 class AdvancedHeapWalkContext: public HeapWalkContext {
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 jint _heap_filter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 KlassHandle _klass_filter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 const jvmtiHeapCallbacks* _heap_callbacks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1781
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 AdvancedHeapWalkContext() : HeapWalkContext(false) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1784
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 AdvancedHeapWalkContext(jint heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 KlassHandle klass_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 const jvmtiHeapCallbacks* heap_callbacks) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 HeapWalkContext(true),
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 _heap_filter(heap_filter),
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 _klass_filter(klass_filter),
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 _heap_callbacks(heap_callbacks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1793
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 jint heap_filter() const { return _heap_filter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 KlassHandle klass_filter() const { return _klass_filter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 const jvmtiHeapReferenceCallback heap_reference_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 return _heap_callbacks->heap_reference_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 return _heap_callbacks->primitive_field_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 return _heap_callbacks->array_primitive_value_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 return _heap_callbacks->string_primitive_value_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1811
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 // The CallbackInvoker is a class with static functions that the heap walk can call
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // mode is for the newer FollowReferences function which supports a lot of
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 // additional callbacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 class CallbackInvoker : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 // heap walk styles
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 enum { basic, advanced };
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 static int _heap_walk_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 static bool is_basic_heap_walk() { return _heap_walk_type == basic; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1824
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 // context for basic style heap walk
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 static BasicHeapWalkContext _basic_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 static BasicHeapWalkContext* basic_context() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 assert(_basic_context.is_valid(), "invalid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 return &_basic_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 // context for advanced style heap walk
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 static AdvancedHeapWalkContext _advanced_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 static AdvancedHeapWalkContext* advanced_context() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 assert(_advanced_context.is_valid(), "invalid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 return &_advanced_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // context needed for all heap walks
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 static JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 static const void* _user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 static GrowableArray<oop>* _visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 static JvmtiTagMap* tag_map() { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 static const void* user_data() { return _user_data; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 static GrowableArray<oop>* visit_stack() { return _visit_stack; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1848
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 // if the object hasn't been visited then push it onto the visit stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // so that it will be visited later
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 static inline bool check_for_visit(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1855
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // invoke basic style callbacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 static inline bool invoke_basic_heap_root_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 (jvmtiHeapRootKind root_kind, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 static inline bool invoke_basic_stack_ref_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 int slot, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 static inline bool invoke_basic_object_reference_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1864
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 // invoke advanced style callbacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 static inline bool invoke_advanced_heap_root_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 (jvmtiHeapReferenceKind ref_kind, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 static inline bool invoke_advanced_stack_ref_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 jmethodID method, jlocation bci, jint slot, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 static inline bool invoke_advanced_object_reference_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1873
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // used to report the value of primitive fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 static inline bool report_primitive_field
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1877
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 // initialize for basic mode
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 BasicHeapWalkContext context);
a61af66fc99e Initial load
duke
parents:
diff changeset
1884
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 // initialize for advanced mode
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 AdvancedHeapWalkContext context);
a61af66fc99e Initial load
duke
parents:
diff changeset
1890
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // functions to report roots
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 jmethodID m, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 jmethodID method, jlocation bci, jint slot, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1897
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // functions to report references
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 static inline bool report_class_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 static inline bool report_class_loader_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 static inline bool report_signers_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 static inline bool report_protection_domain_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 static inline bool report_superclass_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 static inline bool report_interface_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 static inline bool report_field_reference(oop referrer, oop referree, jint slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 static inline bool report_primitive_array_values(oop array);
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 static inline bool report_string_value(oop str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1914
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // statics
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 int CallbackInvoker::_heap_walk_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 BasicHeapWalkContext CallbackInvoker::_basic_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 JvmtiTagMap* CallbackInvoker::_tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 const void* CallbackInvoker::_user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 GrowableArray<oop>* CallbackInvoker::_visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1922
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 // initialize for basic heap walk (IterateOverReachableObjects et al)
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 BasicHeapWalkContext context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 _visit_stack = visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 _user_data = user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 _basic_context = context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 _advanced_context.invalidate(); // will trigger assertion if used
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 _heap_walk_type = basic;
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1935
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 // initialize for advanced heap walk (FollowReferences)
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 AdvancedHeapWalkContext context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 _visit_stack = visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 _user_data = user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 _advanced_context = context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 _basic_context.invalidate(); // will trigger assertion if used
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 _heap_walk_type = advanced;
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // invoke basic style heap root callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1953
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // if we heap roots should be reported
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1959
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 jvmtiIterationControl control = (*cb)(root_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 // push root to visit stack when following references
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 if (control == JVMTI_ITERATION_CONTINUE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 basic_context()->object_ref_callback() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 visit_stack()->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 return control != JVMTI_ITERATION_ABORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1973
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 // invoke basic style stack ref callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 jlong thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 jint slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // if we stack refs should be reported
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 jvmtiIterationControl control = (*cb)(root_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 // push root to visit stack when following references
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 if (control == JVMTI_ITERATION_CONTINUE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 basic_context()->object_ref_callback() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 visit_stack()->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 return control != JVMTI_ITERATION_ABORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2006
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 // invoke basic style object reference callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 oop referrer,
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 oop referree,
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 jint index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2012
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 assert(ServiceUtil::visible_oop(referrer), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 assert(ServiceUtil::visible_oop(referree), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 BasicHeapWalkContext* context = basic_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2017
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 // callback requires the referrer's tag. If it's the same referrer
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 // as the last call then we use the cached value.
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 jlong referrer_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 if (referrer == context->last_referrer()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 referrer_tag = context->last_referrer_tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 } else {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2024 referrer_tag = tag_for(tag_map(), referrer);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2026
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 // do the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 CallbackWrapper wrapper(tag_map(), referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 jvmtiObjectReferenceCallback cb = context->object_ref_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 jvmtiIterationControl control = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 referrer_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2037
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 // record referrer and referrer tag. For self-references record the
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 // tag value from the callback as this might differ from referrer_tag.
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 context->set_last_referrer(referrer);
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 if (referrer == referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 context->set_last_referrer_tag(*wrapper.obj_tag_p());
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 context->set_last_referrer_tag(referrer_tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2046
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 if (control == JVMTI_ITERATION_CONTINUE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 return check_for_visit(referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 return control != JVMTI_ITERATION_ABORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2053
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 // invoke advanced style heap root callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2060
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 // check that callback is provided
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2066
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2071
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // setup the callback wrapper
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2074
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2084
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 jint res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 NULL, // referrer info
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 0, // referrer_class_tag is 0 for heap root
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 NULL, // referrer_tag_p
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 len,
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 return false;// referrer class tag
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 if (res & JVMTI_VISIT_OBJECTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2103
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 // report a reference from a thread stack to an object
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 jlong thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 jlong tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 int depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 jlocation bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 jint slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2114
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 // check that callback is provider
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2127
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // setup the callback wrapper
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2130
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2137
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 // setup the referrer info
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 jvmtiHeapReferenceInfo reference_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 reference_info.stack_local.thread_tag = thread_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 reference_info.stack_local.thread_id = tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 reference_info.stack_local.depth = depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 reference_info.stack_local.method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 reference_info.stack_local.location = bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 reference_info.stack_local.slot = slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
2146
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 // call into the agent
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 int res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 &reference_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 0, // referrer_class_tag is 0 for heap root (stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 NULL, // referrer_tag is 0 for root
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 len,
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2160
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 if (res & JVMTI_VISIT_OBJECTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 // invoke the object reference callback to report a reference
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 oop referrer,
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 jint index)
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // field index is only valid field in reference_info
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 static jvmtiHeapReferenceInfo reference_info = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2187
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 assert(ServiceUtil::visible_oop(referrer), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2190
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2192
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 // check that callback is provider
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2198
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2203
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 // setup the callback wrapper
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2213
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 // field index is only valid field in reference_info
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 reference_info.field.index = index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2216
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 int res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 wrapper.referrer_klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 wrapper.referrer_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 len,
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2230
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 if (res & JVMTI_VISIT_OBJECTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2239
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 // report a "simple root"
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2245
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 // map to old style root kind
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 return invoke_basic_heap_root_callback(root_kind, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 assert(is_advanced_heap_walk(), "wrong heap walk type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 return invoke_advanced_heap_root_callback(kind, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2255
a61af66fc99e Initial load
duke
parents:
diff changeset
2256
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 // invoke the primitive array values
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 assert(obj->is_typeArray(), "not a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2260
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 assert(context->array_primitive_value_callback() != NULL, "no callback");
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2270
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2277
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 &wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 return (!(res & JVMTI_VISIT_ABORT));
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2285
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 // invoke the string value callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 inline bool CallbackInvoker::report_string_value(oop str) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
2288 assert(str->klass() == SystemDictionary::String_klass(), "not a string");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2289
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 assert(context->string_primitive_value_callback() != NULL, "no callback");
a61af66fc99e Initial load
duke
parents:
diff changeset
2292
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 if (is_filtered_by_klass_filter(str, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2297
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 CallbackWrapper wrapper(tag_map(), str);
a61af66fc99e Initial load
duke
parents:
diff changeset
2299
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2306
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 int res = invoke_string_value_callback(context->string_primitive_value_callback(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 &wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 str,
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 return (!(res & JVMTI_VISIT_ABORT));
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2314
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // invoke the primitive field callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 jint index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 address addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 char type)
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 // for primitive fields only the index will be set
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 static jvmtiHeapReferenceInfo reference_info = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 assert(context->primitive_field_callback() != NULL, "no callback");
a61af66fc99e Initial load
duke
parents:
diff changeset
2327
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2332
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2334
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2341
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // the field index in the referrer
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 reference_info.field.index = index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2344
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 // map the type
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2347
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 // setup the jvalue
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 jvalue value;
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 copy_to_jvalue(&value, addr, value_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2351
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 int res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 &reference_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 value_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 return (!(res & JVMTI_VISIT_ABORT));
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 // instance field
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 inline bool CallbackInvoker::report_primitive_instance_field(oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 jint index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 address value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 char type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD,
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2375
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 // static field
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 inline bool CallbackInvoker::report_primitive_static_field(oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 jint index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 address value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 char type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2387
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 // report a JNI local (root object) to the profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 inline bool CallbackInvoker::report_jni_local_root(jlong thread_tag, jlong tid, jint depth, jmethodID m, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 m,
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 thread_tag, tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 m,
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 (jlocation)-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2407
a61af66fc99e Initial load
duke
parents:
diff changeset
2408
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 // report a local (stack reference, root object)
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 jlong tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 jlocation bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 jint slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2435
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 // report an object referencing a class.
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2444
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 // report a class referencing its class loader.
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2453
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 // report a class referencing its signers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 // report a class referencing its protection domain..
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2471
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 // report a class referencing its superclass.
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 // Send this to be consistent with past implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2481
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 // report a class referencing one of its interfaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2490
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 // report a class referencing one of its static fields.
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2499
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 // report an array referencing an element object
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2508
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 // report an object referencing an instance field object
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2517
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 // report an array referencing an element object
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2526
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 // A supporting closure used to process simple roots
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 class SimpleRootsClosure : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 jvmtiHeapReferenceKind _kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 bool _continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2532
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 jvmtiHeapReferenceKind root_kind() { return _kind; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2534
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 void set_kind(jvmtiHeapReferenceKind kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 _kind = kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 _continue = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2540
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 inline bool stopped() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 return !_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2544
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 void do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // iteration has terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2550
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // ignore null or deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 if (o == NULL || o == JNIHandles::deleted_handle()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2556
6738
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2557 assert(Universe::heap()->is_in_reserved(o), "should be impossible");
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2558
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 jvmtiHeapReferenceKind kind = root_kind();
6738
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2560 if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // SystemDictionary::always_strong_oops_do reports the application
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 // class loader as a root. We want this root to be reported as
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 // a root kind of "OTHER" rather than "SYSTEM_CLASS".
6738
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2564 if (!o->is_instanceMirror()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 kind = JVMTI_HEAP_REFERENCE_OTHER;
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 }
6738
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2567 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2568
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 // some objects are ignored - in the case of simple
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2145
diff changeset
2570 // roots it's mostly Symbol*s that we are skipping
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 // here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 if (!ServiceUtil::visible_oop(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2575
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 _continue = CallbackInvoker::report_simple_root(kind, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2578
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2580 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2582
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 // A supporting closure used to process JNI locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 class JNILocalRootsClosure : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 jlong _thread_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 jlong _tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 jint _depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 jmethodID _method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 bool _continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 _thread_tag = thread_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 _tid = tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 _depth = depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 _method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 _continue = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2599
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 inline bool stopped() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 return !_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2603
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 void do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 // iteration has terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2609
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 // ignore null or deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 if (o == NULL || o == JNIHandles::deleted_handle()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2615
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 if (!ServiceUtil::visible_oop(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2619
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2623 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2625
a61af66fc99e Initial load
duke
parents:
diff changeset
2626
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 // A VM operation to iterate over objects that are reachable from
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 // a set of roots or an initial object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 // For VM_HeapWalkOperation the set of roots used is :-
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 // - All JNI global references
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 // - All inflated monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 // - All classes loaded by the boot class loader (or all classes
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 // in the event that class unloading is disabled)
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 // - All java threads
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 // - For each java thread then all locals and JNI local references
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 // on the thread's execution stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 // - All visible/explainable objects from Universes::oops_do
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 class VM_HeapWalkOperation: public VM_Operation {
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 initial_visit_stack_size = 4000
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2646
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 bool _is_advanced_heap_walk; // indicates FollowReferences
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 Handle _initial_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 GrowableArray<oop>* _visit_stack; // the visit stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2651
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 bool _collecting_heap_roots; // are we collecting roots
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 bool _following_object_refs; // are we following object references
a61af66fc99e Initial load
duke
parents:
diff changeset
2654
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 bool _reporting_primitive_fields; // optional reporting
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 bool _reporting_primitive_array_values;
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 bool _reporting_string_values;
a61af66fc99e Initial load
duke
parents:
diff changeset
2658
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 GrowableArray<oop>* create_visit_stack() {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6171
diff changeset
2660 return new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(initial_visit_stack_size, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2662
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 JvmtiTagMap* tag_map() const { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 Handle initial_object() const { return _initial_object; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2667
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 bool is_following_references() const { return _following_object_refs; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2669
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 bool is_reporting_primitive_fields() const { return _reporting_primitive_fields; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 bool is_reporting_string_values() const { return _reporting_string_values; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2673
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 GrowableArray<oop>* visit_stack() const { return _visit_stack; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2675
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 // iterate over the various object types
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 inline bool iterate_over_array(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 inline bool iterate_over_type_array(oop o);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2679 inline bool iterate_over_class(oop o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 inline bool iterate_over_object(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2681
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 // root collection
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 inline bool collect_simple_roots();
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 inline bool collect_stack_roots();
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
2686
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 // visit an object
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 inline bool visit(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2689
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 BasicHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 const void* user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
2695
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 AdvancedHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 const void* user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
2700
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 ~VM_HeapWalkOperation();
a61af66fc99e Initial load
duke
parents:
diff changeset
2702
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 VMOp_Type type() const { return VMOp_HeapWalkOperation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 void doit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2706
a61af66fc99e Initial load
duke
parents:
diff changeset
2707
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 BasicHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 _is_advanced_heap_walk = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 _initial_object = initial_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 _following_object_refs = (callbacks.object_ref_callback() != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 _reporting_primitive_fields = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 _reporting_primitive_array_values = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 _reporting_string_values = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 _visit_stack = create_visit_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
2720
a61af66fc99e Initial load
duke
parents:
diff changeset
2721
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks);
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2724
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 AdvancedHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 _is_advanced_heap_walk = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 _initial_object = initial_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 _following_object_refs = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 _visit_stack = create_visit_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
2737
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks);
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2740
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 VM_HeapWalkOperation::~VM_HeapWalkOperation() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 if (_following_object_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 assert(_visit_stack != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 delete _visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 _visit_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2748
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 // an array references its class and has a reference to
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 // each element in the array
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 objArrayOop array = objArrayOop(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2753
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 // array reference to its class
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6738
diff changeset
2755 oop mirror = ObjArrayKlass::cast(array->klass())->java_mirror();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 if (!CallbackInvoker::report_class_reference(o, mirror)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2759
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 // iterate over the array and report each reference to a
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 // non-null element
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 for (int index=0; index<array->length(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 oop elem = array->obj_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 if (elem == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2767
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 // report the array reference o[index] = elem
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 if (!CallbackInvoker::report_array_element_reference(o, elem, index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2775
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // a type array references its class
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2778 Klass* k = o->klass();
6983
070d523b96a7 8001471: Klass::cast() does nothing
hseigel
parents: 6871
diff changeset
2779 oop mirror = k->java_mirror();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 if (!CallbackInvoker::report_class_reference(o, mirror)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2783
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 // report the array contents if required
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 if (is_reporting_primitive_array_values()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 if (!CallbackInvoker::report_primitive_array_values(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2792
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 // verify that a static oop field is in range
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2794 static inline bool verify_static_oop(InstanceKlass* ik,
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2795 oop mirror, int offset) {
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2796 address obj_p = (address)mirror + offset;
6735
aed758eda82a 7195833: NPG: Rename instanceClassLoaderKlass, instanceRefKlass and instanceMirrorKlass
coleenp
parents: 6725
diff changeset
2797 address start = (address)InstanceMirrorKlass::start_of_static_fields(mirror);
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2798 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 assert(end >= start, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2800
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 if (obj_p >= start && obj_p < end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2807
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 // a class references its super class, interfaces, class loader, ...
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 // and finally its static fields
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2810 inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 int i;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2812 Klass* klass = java_lang_Class::as_Klass(java_class);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2813
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 if (klass->oop_is_instance()) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2815 InstanceKlass* ik = InstanceKlass::cast(klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2816
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 // ignore the class if it's has been initialized yet
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 if (!ik->is_linked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2821
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 // get the java mirror
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 oop mirror = klass->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2824
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 // super (only if something more interesting than java.lang.Object)
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2826 Klass* java_super = ik->java_super();
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
2827 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
6983
070d523b96a7 8001471: Klass::cast() does nothing
hseigel
parents: 6871
diff changeset
2828 oop super = java_super->java_mirror();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 // class loader
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 oop cl = ik->class_loader();
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 if (cl != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2841
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 // protection domain
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 oop pd = ik->protection_domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 if (pd != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2849
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 // signers
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 oop signers = ik->signers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 if (signers != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 if (!CallbackInvoker::report_signers_reference(mirror, signers)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2857
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // references from the constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2860 ConstantPool* const pool = ik->constants();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 for (int i = 1; i < pool->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 constantTag tag = pool->tag_at(i).value();
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 if (tag.is_string() || tag.is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 oop entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 if (tag.is_string()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 entry = pool->resolved_string_at(i);
6855
bbeecede56dd 8000459: assert(java_lang_String::is_instance(entry)) failure with various mlvm tests.
jiangli
parents: 6738
diff changeset
2867 // If the entry is non-null it is resolved.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2868 if (entry == NULL) continue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 } else {
6983
070d523b96a7 8001471: Klass::cast() does nothing
hseigel
parents: 6871
diff changeset
2870 entry = pool->resolved_klass_at(i)->java_mirror();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2878
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 // interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 // (These will already have been reported as references from the constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 // but are specified by IterateOverReachableObjects and must be reported).
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2882 Array<Klass*>* interfaces = ik->local_interfaces();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 for (i = 0; i < interfaces->length(); i++) {
6983
070d523b96a7 8001471: Klass::cast() does nothing
hseigel
parents: 6871
diff changeset
2884 oop interf = ((Klass*)interfaces->at(i))->java_mirror();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 if (interf == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 if (!CallbackInvoker::report_interface_reference(mirror, interf)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2892
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 // iterate over the static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2894
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2895 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 for (i=0; i<field_map->field_count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 ClassFieldDescriptor* field = field_map->field_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 char type = field->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 if (!is_primitive_field_type(type)) {
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2900 oop fld_o = mirror->obj_field(field->field_offset());
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2901 assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 if (fld_o != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 if (is_reporting_primitive_fields()) {
2377
57552dca1708 7029509: nightly failures after static fields in Class
never
parents: 2376
diff changeset
2911 address addr = (address)mirror + field->field_offset();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2921
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2924
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2927
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 // an object references a class and its instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 // (static fields are ignored here as we report these as
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 // references from the class).
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 // reference to the class
6983
070d523b96a7 8001471: Klass::cast() does nothing
hseigel
parents: 6871
diff changeset
2933 if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2936
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 // iterate over instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 for (int i=0; i<field_map->field_count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 ClassFieldDescriptor* field = field_map->field_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 char type = field->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 if (!is_primitive_field_type(type)) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2943 oop fld_o = o->obj_field(field->field_offset());
4929
2b150750d53d 7130993: nsk/jdi/ReferenceType/instances/instances004 fails with JFR: assert(ServiceUtil::visible_oop(obj))
sspitsyn
parents: 3816
diff changeset
2944 // ignore any objects that aren't visible to profiler
2b150750d53d 7130993: nsk/jdi/ReferenceType/instances/instances004 fails with JFR: assert(ServiceUtil::visible_oop(obj))
sspitsyn
parents: 3816
diff changeset
2945 if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2946 assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2947 "have references to Klass* anymore");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 if (is_reporting_primitive_fields()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 // primitive instance field
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 address addr = (address)o + field->field_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2964
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 // if the object is a java.lang.String
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 if (is_reporting_string_values() &&
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
2967 o->klass() == SystemDictionary::String_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 if (!CallbackInvoker::report_string_value(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2974
a61af66fc99e Initial load
duke
parents:
diff changeset
2975
3816
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
2976 // Collects all simple (non-stack) roots except for threads;
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
2977 // threads are handled in collect_stack_roots() as an optimization.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 // if there's a heap root callback provided then the callback is
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 // invoked for each simple root.
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 // if an object reference callback is provided then all simple
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 // roots are pushed onto the marking stack so that they can be
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 // processed later
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 inline bool VM_HeapWalkOperation::collect_simple_roots() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 SimpleRootsClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
2986
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 // JNI globals
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 JNIHandles::oops_do(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 if (blk.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2993
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 // Preloaded classes and loader from the system dictionary
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 SystemDictionary::always_strong_oops_do(&blk);
6738
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2997 KlassToOopClosure klass_blk(&blk);
ec98e58952b2 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 6735
diff changeset
2998 ClassLoaderDataGraph::always_strong_oops_do(&blk, &klass_blk, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 if (blk.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3002
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 // Inflated monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 ObjectSynchronizer::oops_do(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 if (blk.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3009
3816
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3010 // threads are now handled in collect_stack_roots()
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3011
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 // Other kinds of roots maintained by HotSpot
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 // Many of these won't be visible but others (such as instances of important
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 // exceptions) will be visible.
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 Universe::oops_do(&blk);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3017
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3018 // If there are any non-perm roots in the code cache, visit them.
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3019 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3020 CodeBlobToOopClosure look_in_blobs(&blk, false);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3021 CodeCache::scavenge_root_nmethods_do(&look_in_blobs);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3022
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3025
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 // Walk the stack of a given thread and find all references (locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // and JNI calls) and report these as stack references
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 JNILocalRootsClosure* blk)
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 oop threadObj = java_thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 assert(threadObj != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3033
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 // only need to get the thread's tag once per thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 jlong thread_tag = tag_for(_tag_map, threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3036
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 // also need the thread id
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 jlong tid = java_lang_Thread::thread_id(threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3039
a61af66fc99e Initial load
duke
parents:
diff changeset
3040
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 if (java_thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3042
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 // vframes are resource allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 Thread* current_thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 ResourceMark rm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 HandleMark hm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3047
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 RegisterMap reg_map(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 frame f = java_thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3051
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 bool is_top_frame = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 int depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 frame* last_entry_frame = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3055
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 while (vf != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 if (vf->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3058
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 // java frame (interpreted, compiled, ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 javaVFrame *jvf = javaVFrame::cast(vf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3061
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // the jmethodID
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 jmethodID method = jvf->method()->jmethod_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
3064
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 if (!(jvf->method()->is_native())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 jlocation bci = (jlocation)jvf->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 StackValueCollection* locals = jvf->locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 for (int slot=0; slot<locals->size(); slot++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 if (locals->at(slot)->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 oop o = locals->obj_at(slot)();
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 if (o == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3074
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 // stack reference
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method,
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 bci, slot, o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 blk->set_context(thread_tag, tid, depth, method);
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 if (is_top_frame) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 // JNI locals for the top frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 java_thread->active_handles()->oops_do(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 if (last_entry_frame != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 // JNI locals for the entry frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 assert(last_entry_frame->is_entry_frame(), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 last_entry_frame = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 // externalVFrame - for an entry frame then we report the JNI locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 // when we find the corresponding javaVFrame
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 frame* fr = vf->frame_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 assert(fr != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 if (fr->is_entry_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 last_entry_frame = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3106
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 vf = vf->sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 is_top_frame = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 // no last java frame but there may be JNI locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 blk->set_context(thread_tag, tid, 0, (jmethodID)NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 java_thread->active_handles()->oops_do(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3117
a61af66fc99e Initial load
duke
parents:
diff changeset
3118
3816
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3119 // Collects the simple roots for all threads and collects all
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3120 // stack roots - for each thread it walks the execution
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 // stack to find all references and local JNI refs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 inline bool VM_HeapWalkOperation::collect_stack_roots() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 JNILocalRootsClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 oop threadObj = thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
3816
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3127 // Collect the simple root for this thread before we
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3128 // collect its stack roots
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3129 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3130 threadObj)) {
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3131 return false;
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3132 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 if (!collect_stack_roots(thread, &blk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3140
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 // visit an object
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 // first mark the object as visited
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 // second get all the outbound references from this object (in other words, all
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 // the objects referenced by this object).
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 bool VM_HeapWalkOperation::visit(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 // mark object as visited
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 assert(!ObjectMarker::visited(o), "can't visit same object more than once");
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 ObjectMarker::mark(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3150
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 // instance
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 if (o->is_instance()) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
3153 if (o->klass() == SystemDictionary::Class_klass()) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
3154 if (!java_lang_Class::is_primitive(o)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 // a java.lang.Class
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
3156 return iterate_over_class(o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 return iterate_over_object(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3162
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 // object array
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 if (o->is_objArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 return iterate_over_array(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3167
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 // type array
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 if (o->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 return iterate_over_type_array(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3172
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3175
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 void VM_HeapWalkOperation::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 ObjectMarkerController marker;
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 ClassFieldMapCacheMark cm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3180
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 assert(visit_stack()->is_empty(), "visit stack must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
3182
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 // the heap walk starts with an initial object or the heap roots
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 if (initial_object().is_null()) {
3815
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3185 // If either collect_stack_roots() or collect_simple_roots()
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3186 // returns false at this point, then there are no mark bits
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3187 // to reset.
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3188 ObjectMarker::set_needs_reset(false);
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3189
3816
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3190 // Calling collect_stack_roots() before collect_simple_roots()
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3191 // can result in a big performance boost for an agent that is
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3192 // focused on analyzing references in the thread stacks.
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3193 if (!collect_stack_roots()) return;
88dce6a60ac8 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 3815
diff changeset
3194
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 if (!collect_simple_roots()) return;
3815
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3196
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3197 // no early return so enable heap traversal to reset the mark bits
d425748f2203 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 3363
diff changeset
3198 ObjectMarker::set_needs_reset(true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 visit_stack()->push(initial_object()());
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3202
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 // object references required
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 if (is_following_references()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3205
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 // visit each object until all reachable objects have been
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 // visited or the callback asked to terminate the iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 while (!visit_stack()->is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 oop o = visit_stack()->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 if (!ObjectMarker::visited(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 if (!visit(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3218
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 // iterate over all objects that are reachable from a set of roots
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 jvmtiStackReferenceCallback stack_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 jvmtiObjectReferenceCallback object_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 VM_HeapWalkOperation op(this, Handle(), context, user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3229
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 // iterate over all objects that are reachable from a given object
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 jvmtiObjectReferenceCallback object_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 oop obj = JNIHandles::resolve(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 Handle initial_object(Thread::current(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3236
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 VM_HeapWalkOperation op(this, initial_object, context, user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3242
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 // follow references from an initial object or the GC roots
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 void JvmtiTagMap::follow_references(jint heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 KlassHandle klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 jobject object,
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 const jvmtiHeapCallbacks* callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 const void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 oop obj = JNIHandles::resolve(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 Handle initial_object(Thread::current(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3252
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 VM_HeapWalkOperation op(this, initial_object, context, user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3258
a61af66fc99e Initial load
duke
parents:
diff changeset
3259
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3260 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
2145
c1a0ede55d6f 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 2125
diff changeset
3261 // No locks during VM bring-up (0 threads) and no safepoints after main
c1a0ede55d6f 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 2125
diff changeset
3262 // thread creation and before VMThread creation (1 thread); initial GC
c1a0ede55d6f 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 2125
diff changeset
3263 // verification can happen in that window which gets to here.
c1a0ede55d6f 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 2125
diff changeset
3264 assert(Threads::number_of_threads() <= 1 ||
c1a0ede55d6f 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 2125
diff changeset
3265 SafepointSynchronize::is_at_safepoint(),
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3266 "must be executed at a safepoint");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 if (JvmtiEnv::environments_might_exist()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 JvmtiEnvIterator it;
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 JvmtiTagMap* tag_map = env->tag_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 if (tag_map != NULL && !tag_map->is_empty()) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3272 tag_map->do_weak_oops(is_alive, f);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3277
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3278 void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3279
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 // does this environment have the OBJECT_FREE event enabled
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3282
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 // counters used for trace message
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 int freed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 int moved = 0;
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3286
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3287 JvmtiTagHashmap* hashmap = this->hashmap();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3288
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 // reenable sizing (if disabled)
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3290 hashmap->set_resizing_enabled(true);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3291
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3292 // if the hashmap is empty then we can skip it
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3293 if (hashmap->_entry_count == 0) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3294 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3296
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3297 // now iterate through each entry in the table
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3298
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3299 JvmtiTagHashmapEntry** table = hashmap->table();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3300 int size = hashmap->size();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3301
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3302 JvmtiTagHashmapEntry* delayed_add = NULL;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3303
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3304 for (int pos = 0; pos < size; ++pos) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3305 JvmtiTagHashmapEntry* entry = table[pos];
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3306 JvmtiTagHashmapEntry* prev = NULL;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3307
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3308 while (entry != NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3309 JvmtiTagHashmapEntry* next = entry->next();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3310
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3311 oop* obj = entry->object_addr();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3312
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3313 // has object been GC'ed
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3314 if (!is_alive->do_object_b(entry->object())) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3315 // grab the tag
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3316 jlong tag = entry->tag();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3317 guarantee(tag != 0, "checking");
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3318
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3319 // remove GC'ed entry from hashmap and return the
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3320 // entry to the free list
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3321 hashmap->remove(prev, pos, entry);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3322 destroy_entry(entry);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3323
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3324 // post the event to the profiler
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3325 if (post_object_free) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3326 JvmtiExport::post_object_free(env(), tag);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3327 }
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3328
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3329 ++freed;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3330 } else {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3331 f->do_oop(entry->object_addr());
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3332 oop new_oop = entry->object();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3333
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3334 // if the object has moved then re-hash it and move its
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3335 // entry to its new location.
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3336 unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3337 if (new_pos != (unsigned int)pos) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3338 if (prev == NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3339 table[pos] = next;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3340 } else {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3341 prev->set_next(next);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3343 if (new_pos < (unsigned int)pos) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 entry->set_next(table[new_pos]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 table[new_pos] = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 } else {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3347 // Delay adding this entry to it's new position as we'd end up
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3348 // hitting it again during this iteration.
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3349 entry->set_next(delayed_add);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3350 delayed_add = entry;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3352 moved++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 } else {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3354 // object didn't move
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3355 prev = entry;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3358
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3359 entry = next;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3362
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3363 // Re-add all the entries which were kept aside
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3364 while (delayed_add != NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3365 JvmtiTagHashmapEntry* next = delayed_add->next();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3366 unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3367 delayed_add->set_next(table[pos]);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3368 table[pos] = delayed_add;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3369 delayed_add = next;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3371
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 // stats
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 if (TraceJVMTIObjectTagging) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3374 int post_total = hashmap->_entry_count;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 int pre_total = post_total + freed;
a61af66fc99e Initial load
duke
parents:
diff changeset
3376
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3377 tty->print_cr("(%d->%d, %d freed, %d total moves)",
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3378 pre_total, post_total, freed, moved);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 }