annotate src/share/vm/prims/jvmtiTagMap.cpp @ 3992:d1bdeef3e3e2

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