annotate src/share/vm/prims/jvmtiTagMap.cpp @ 3762:5c0a3c1858b1

7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359 Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675. Reviewed-by: brutisso
author ysr
date Thu, 02 Jun 2011 10:23:36 -0700
parents 167b70ff3abc
children d425748f2203
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;
a61af66fc99e Initial load
duke
parents:
diff changeset
1650
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 static void init(); // initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 static void done(); // clean-up
a61af66fc99e Initial load
duke
parents:
diff changeset
1654
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 static inline void mark(oop o); // mark an object
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 static inline bool visited(oop o); // check if object has been visited
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1661
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // initialize ObjectMarker - prepares for object marking
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 void ObjectMarker::init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 assert(Thread::current()->is_VM_thread(), "must be VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // prepare heap for iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // create stacks for interesting headers
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 _saved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(4000, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 _saved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 BiasedLocking::preserve_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1677
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // Object marking is done so restore object headers
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 void ObjectMarker::done() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 // iterate over all objects and restore the mark bits to
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 // their initial value
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 RestoreMarksClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 Universe::heap()->object_iterate(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // When sharing is enabled we need to restore the headers of the objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 // in the readwrite space too.
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 if (UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 GenCollectedHeap* gch = GenCollectedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 gen->rw_space()->object_iterate(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 // now restore the interesting headers
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 for (int i = 0; i < _saved_oop_stack->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 oop o = _saved_oop_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 markOop mark = _saved_mark_stack->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 o->set_mark(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1699
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 BiasedLocking::restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1703
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // free the stacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 delete _saved_oop_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 delete _saved_mark_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1708
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // mark an object
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 inline void ObjectMarker::mark(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 assert(Universe::heap()->is_in(o), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 assert(!o->mark()->is_marked(), "should only mark an object once");
a61af66fc99e Initial load
duke
parents:
diff changeset
1713
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 // object's mark word
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 markOop mark = o->mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
1716
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 if (mark->must_be_preserved(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 _saved_mark_stack->push(mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 _saved_oop_stack->push(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1721
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // mark the object
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 o->set_mark(markOopDesc::prototype()->set_marked());
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1725
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // return true if object is marked
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 inline bool ObjectMarker::visited(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 return o->mark()->is_marked();
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1730
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 // Stack allocated class to help ensure that ObjectMarker is used
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // correctly. Constructor initializes ObjectMarker, destructor calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // ObjectMarker's done() function to restore object headers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 class ObjectMarkerController : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 ObjectMarkerController() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 ObjectMarker::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 ~ObjectMarkerController() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 ObjectMarker::done();
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1743
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // (not performance critical as only used for roots)
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 switch (kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR;
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER;
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER;
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // Base class for all heap walk contexts. The base class maintains a flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // to indicate if the context is valid or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 class HeapWalkContext VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 bool _valid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 HeapWalkContext(bool valid) { _valid = valid; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 void invalidate() { _valid = false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 bool is_valid() const { return _valid; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1770
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 // A basic heap walk context for the deprecated heap walking functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 // The context for a basic heap walk are the callbacks and fields used by
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 // the referrer caching scheme.
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 class BasicHeapWalkContext: public HeapWalkContext {
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 jvmtiHeapRootCallback _heap_root_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 jvmtiStackReferenceCallback _stack_ref_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 jvmtiObjectReferenceCallback _object_ref_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1779
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 // used for caching
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 oop _last_referrer;
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 jlong _last_referrer_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 BasicHeapWalkContext() : HeapWalkContext(false) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1786
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 BasicHeapWalkContext(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 HeapWalkContext(true),
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 _heap_root_callback(heap_root_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 _stack_ref_callback(stack_ref_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 _object_ref_callback(object_ref_callback),
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 _last_referrer(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 _last_referrer_tag(0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 jvmtiHeapRootCallback heap_root_callback() const { return _heap_root_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 jvmtiStackReferenceCallback stack_ref_callback() const { return _stack_ref_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1802
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 oop last_referrer() const { return _last_referrer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 void set_last_referrer(oop referrer) { _last_referrer = referrer; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 jlong last_referrer_tag() const { return _last_referrer_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1808
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // The advanced heap walk context for the FollowReferences functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // The context is the callbacks, and the fields used for filtering.
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 class AdvancedHeapWalkContext: public HeapWalkContext {
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 jint _heap_filter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 KlassHandle _klass_filter;
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 const jvmtiHeapCallbacks* _heap_callbacks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1816
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 AdvancedHeapWalkContext() : HeapWalkContext(false) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1819
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 AdvancedHeapWalkContext(jint heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 KlassHandle klass_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 const jvmtiHeapCallbacks* heap_callbacks) :
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 HeapWalkContext(true),
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 _heap_filter(heap_filter),
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 _klass_filter(klass_filter),
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 _heap_callbacks(heap_callbacks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 jint heap_filter() const { return _heap_filter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 KlassHandle klass_filter() const { return _klass_filter; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1832
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 const jvmtiHeapReferenceCallback heap_reference_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 return _heap_callbacks->heap_reference_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 return _heap_callbacks->primitive_field_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 return _heap_callbacks->array_primitive_value_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 return _heap_callbacks->string_primitive_value_callback;
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 // The CallbackInvoker is a class with static functions that the heap walk can call
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // mode is for the newer FollowReferences function which supports a lot of
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // additional callbacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 class CallbackInvoker : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 // heap walk styles
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 enum { basic, advanced };
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 static int _heap_walk_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 static bool is_basic_heap_walk() { return _heap_walk_type == basic; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // context for basic style heap walk
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 static BasicHeapWalkContext _basic_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 static BasicHeapWalkContext* basic_context() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 assert(_basic_context.is_valid(), "invalid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 return &_basic_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1866
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 // context for advanced style heap walk
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 static AdvancedHeapWalkContext _advanced_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 static AdvancedHeapWalkContext* advanced_context() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 assert(_advanced_context.is_valid(), "invalid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 return &_advanced_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1873
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // context needed for all heap walks
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 static JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 static const void* _user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 static GrowableArray<oop>* _visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1878
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 static JvmtiTagMap* tag_map() { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 static const void* user_data() { return _user_data; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 static GrowableArray<oop>* visit_stack() { return _visit_stack; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1883
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 // if the object hasn't been visited then push it onto the visit stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 // so that it will be visited later
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 static inline bool check_for_visit(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1890
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // invoke basic style callbacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 static inline bool invoke_basic_heap_root_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 (jvmtiHeapRootKind root_kind, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 static inline bool invoke_basic_stack_ref_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 int slot, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 static inline bool invoke_basic_object_reference_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1899
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 // invoke advanced style callbacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 static inline bool invoke_advanced_heap_root_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 (jvmtiHeapReferenceKind ref_kind, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 static inline bool invoke_advanced_stack_ref_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 jmethodID method, jlocation bci, jint slot, oop obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 static inline bool invoke_advanced_object_reference_callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1908
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 // used to report the value of primitive fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 static inline bool report_primitive_field
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1912
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 // initialize for basic mode
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 BasicHeapWalkContext context);
a61af66fc99e Initial load
duke
parents:
diff changeset
1919
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 // initialize for advanced mode
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 AdvancedHeapWalkContext context);
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 // functions to report roots
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 jmethodID m, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 jmethodID method, jlocation bci, jint slot, oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
1932
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // functions to report references
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 static inline bool report_class_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 static inline bool report_class_loader_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 static inline bool report_signers_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 static inline bool report_protection_domain_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 static inline bool report_superclass_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 static inline bool report_interface_reference(oop referrer, oop referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 static inline bool report_field_reference(oop referrer, oop referree, jint slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 static inline bool report_primitive_array_values(oop array);
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 static inline bool report_string_value(oop str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // statics
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 int CallbackInvoker::_heap_walk_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 BasicHeapWalkContext CallbackInvoker::_basic_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 JvmtiTagMap* CallbackInvoker::_tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 const void* CallbackInvoker::_user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 GrowableArray<oop>* CallbackInvoker::_visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // initialize for basic heap walk (IterateOverReachableObjects et al)
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 BasicHeapWalkContext context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 _visit_stack = visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 _user_data = user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 _basic_context = context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 _advanced_context.invalidate(); // will trigger assertion if used
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 _heap_walk_type = basic;
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1970
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 // initialize for advanced heap walk (FollowReferences)
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 GrowableArray<oop>* visit_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 const void* user_data,
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 AdvancedHeapWalkContext context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 _visit_stack = visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 _user_data = user_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 _advanced_context = context;
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 _basic_context.invalidate(); // will trigger assertion if used
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 _heap_walk_type = advanced;
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1983
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 // invoke basic style heap root callback
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 // if we heap roots should be reported
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1994
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 jvmtiIterationControl control = (*cb)(root_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 // push root to visit stack when following references
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 if (control == JVMTI_ITERATION_CONTINUE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 basic_context()->object_ref_callback() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 visit_stack()->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 return control != JVMTI_ITERATION_ABORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // invoke basic style stack ref callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 jlong thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 jint slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2017
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 // if we stack refs should be reported
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2023
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 jvmtiIterationControl control = (*cb)(root_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 // push root to visit stack when following references
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 if (control == JVMTI_ITERATION_CONTINUE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 basic_context()->object_ref_callback() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 visit_stack()->push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 return control != JVMTI_ITERATION_ABORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2041
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 // invoke basic style object reference callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 oop referrer,
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 oop referree,
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 jint index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2047
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 assert(ServiceUtil::visible_oop(referrer), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 assert(ServiceUtil::visible_oop(referree), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 BasicHeapWalkContext* context = basic_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2052
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // callback requires the referrer's tag. If it's the same referrer
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 // as the last call then we use the cached value.
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 jlong referrer_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 if (referrer == context->last_referrer()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 referrer_tag = context->last_referrer_tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 referrer_tag = tag_for(tag_map(), klassOop_if_java_lang_Class(referrer));
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2061
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 // do the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 CallbackWrapper wrapper(tag_map(), referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 jvmtiObjectReferenceCallback cb = context->object_ref_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 jvmtiIterationControl control = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 referrer_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2072
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // record referrer and referrer tag. For self-references record the
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // tag value from the callback as this might differ from referrer_tag.
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 context->set_last_referrer(referrer);
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 if (referrer == referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 context->set_last_referrer_tag(*wrapper.obj_tag_p());
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 context->set_last_referrer_tag(referrer_tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 if (control == JVMTI_ITERATION_CONTINUE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 return check_for_visit(referree);
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 return control != JVMTI_ITERATION_ABORT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2088
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 // invoke advanced style heap root callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2093
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2095
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // check that callback is provided
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2101
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2106
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 // setup the callback wrapper
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2109
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2119
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 jint res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 NULL, // referrer info
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 0, // referrer_class_tag is 0 for heap root
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 NULL, // referrer_tag_p
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 len,
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 return false;// referrer class tag
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 if (res & JVMTI_VISIT_OBJECTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2138
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 // report a reference from a thread stack to an object
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 jlong thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 jlong tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 int depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 jlocation bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 jint slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2151
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 // check that callback is provider
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2157
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2162
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 // setup the callback wrapper
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2165
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2172
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // setup the referrer info
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 jvmtiHeapReferenceInfo reference_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 reference_info.stack_local.thread_tag = thread_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 reference_info.stack_local.thread_id = tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 reference_info.stack_local.depth = depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 reference_info.stack_local.method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 reference_info.stack_local.location = bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 reference_info.stack_local.slot = slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
2181
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2184
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // call into the agent
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 int res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 &reference_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 0, // referrer_class_tag is 0 for heap root (stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 NULL, // referrer_tag is 0 for root
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 len,
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 if (res & JVMTI_VISIT_OBJECTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2204
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
a61af66fc99e Initial load
duke
parents:
diff changeset
2213
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 // invoke the object reference callback to report a reference
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 oop referrer,
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 jint index)
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // field index is only valid field in reference_info
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 static jvmtiHeapReferenceInfo reference_info = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2222
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 assert(ServiceUtil::visible_oop(referrer), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2225
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2227
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 // check that callback is provider
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 if (cb == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2233
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2238
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 // setup the callback wrapper
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 return check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2248
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 // field index is only valid field in reference_info
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 reference_info.field.index = index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2251
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 // for arrays we need the length, otherwise -1
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2254
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 int res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 wrapper.referrer_klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 wrapper.obj_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 wrapper.referrer_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 len,
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2265
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 if (res & JVMTI_VISIT_ABORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 if (res & JVMTI_VISIT_OBJECTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 check_for_visit(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2274
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 // report a "simple root"
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 assert(ServiceUtil::visible_oop(obj), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2280
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 // map to old style root kind
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 return invoke_basic_heap_root_callback(root_kind, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 assert(is_advanced_heap_walk(), "wrong heap walk type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 return invoke_advanced_heap_root_callback(kind, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2290
a61af66fc99e Initial load
duke
parents:
diff changeset
2291
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // invoke the primitive array values
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 assert(obj->is_typeArray(), "not a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2295
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 assert(context->array_primitive_value_callback() != NULL, "no callback");
a61af66fc99e Initial load
duke
parents:
diff changeset
2298
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2303
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2305
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2312
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 &wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 return (!(res & JVMTI_VISIT_ABORT));
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2320
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 // invoke the string value callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 inline bool CallbackInvoker::report_string_value(oop str) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
2323 assert(str->klass() == SystemDictionary::String_klass(), "not a string");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 assert(context->string_primitive_value_callback() != NULL, "no callback");
a61af66fc99e Initial load
duke
parents:
diff changeset
2327
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 if (is_filtered_by_klass_filter(str, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2332
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 CallbackWrapper wrapper(tag_map(), str);
a61af66fc99e Initial load
duke
parents:
diff changeset
2334
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2341
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 int res = invoke_string_value_callback(context->string_primitive_value_callback(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 &wrapper,
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 str,
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 return (!(res & JVMTI_VISIT_ABORT));
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2349
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 // invoke the primitive field callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 jint index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 address addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 char type)
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 // for primitive fields only the index will be set
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 static jvmtiHeapReferenceInfo reference_info = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2359
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 AdvancedHeapWalkContext* context = advanced_context();
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 assert(context->primitive_field_callback() != NULL, "no callback");
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 // apply class filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2367
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 CallbackWrapper wrapper(tag_map(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2369
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 // apply tag filter
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 context->heap_filter())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2376
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 // the field index in the referrer
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 reference_info.field.index = index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2379
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 // map the type
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2382
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 // setup the jvalue
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 jvalue value;
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 copy_to_jvalue(&value, addr, value_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2386
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback();
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 int res = (*cb)(ref_kind,
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 &reference_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 wrapper.klass_tag(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 wrapper.obj_tag_p(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 value_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 (void*)user_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 return (!(res & JVMTI_VISIT_ABORT));
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2397
a61af66fc99e Initial load
duke
parents:
diff changeset
2398
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 // instance field
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 inline bool CallbackInvoker::report_primitive_instance_field(oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 jint index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 address value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 char type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD,
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2410
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 // static field
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 inline bool CallbackInvoker::report_primitive_static_field(oop obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 jint index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 address value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 char type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 value,
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2422
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 // report a JNI local (root object) to the profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 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
2425 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 m,
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 thread_tag, tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 m,
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 (jlocation)-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2442
a61af66fc99e Initial load
duke
parents:
diff changeset
2443
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 // report a local (stack reference, root object)
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 jlong tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 jint depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 jmethodID method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 jlocation bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 jint slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 oop obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 thread_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 tid,
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 depth,
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 slot,
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2470
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 // report an object referencing a class.
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2479
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 // report a class referencing its class loader.
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2488
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 // report a class referencing its signers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2497
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 // report a class referencing its protection domain..
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2506
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 // report a class referencing its superclass.
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 // Send this to be consistent with past implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 // report a class referencing one of its interfaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2525
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 // report a class referencing one of its static fields.
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2534
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 // report an array referencing an element object
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2543
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 // report an object referencing an instance field object
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2552
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 // report an array referencing an element object
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 if (is_basic_heap_walk()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2561
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 // A supporting closure used to process simple roots
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 class SimpleRootsClosure : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 jvmtiHeapReferenceKind _kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 bool _continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2567
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 jvmtiHeapReferenceKind root_kind() { return _kind; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2569
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 void set_kind(jvmtiHeapReferenceKind kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 _kind = kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 _continue = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2575
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 inline bool stopped() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 return !_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2579
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 void do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 // iteration has terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2585
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // ignore null or deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 if (o == NULL || o == JNIHandles::deleted_handle()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2591
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 jvmtiHeapReferenceKind kind = root_kind();
a61af66fc99e Initial load
duke
parents:
diff changeset
2593
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 // many roots are Klasses so we use the java mirror
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 if (o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 klassOop k = (klassOop)o;
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 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
2598 if (o == NULL) {
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2599 // 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
2600 // classes so just ignore them.
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2601 return;
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2602 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2604
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 // SystemDictionary::always_strong_oops_do reports the application
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 // class loader as a root. We want this root to be reported as
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 // a root kind of "OTHER" rather than "SYSTEM_CLASS".
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 kind = JVMTI_HEAP_REFERENCE_OTHER;
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2612
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 // 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
2614 // roots it's mostly Symbol*s that we are skipping
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 // here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 if (!ServiceUtil::visible_oop(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2619
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 _continue = CallbackInvoker::report_simple_root(kind, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2622
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2624 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2626
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 // A supporting closure used to process JNI locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 class JNILocalRootsClosure : public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 jlong _thread_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 jlong _tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 jint _depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 jmethodID _method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 bool _continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 _thread_tag = thread_tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 _tid = tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 _depth = depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 _method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 _continue = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2643
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 inline bool stopped() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 return !_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2647
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 void do_oop(oop* obj_p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 // iteration has terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2653
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 // ignore null or deleted handles
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 oop o = *obj_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 if (o == NULL || o == JNIHandles::deleted_handle()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2659
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 if (!ServiceUtil::visible_oop(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2663
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 // invoke the callback
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2667 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2669
a61af66fc99e Initial load
duke
parents:
diff changeset
2670
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 // A VM operation to iterate over objects that are reachable from
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 // a set of roots or an initial object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 // For VM_HeapWalkOperation the set of roots used is :-
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 // - All JNI global references
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 // - All inflated monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 // - All classes loaded by the boot class loader (or all classes
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 // in the event that class unloading is disabled)
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 // - All java threads
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 // - For each java thread then all locals and JNI local references
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 // on the thread's execution stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 // - All visible/explainable objects from Universes::oops_do
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 class VM_HeapWalkOperation: public VM_Operation {
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 initial_visit_stack_size = 4000
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2690
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 bool _is_advanced_heap_walk; // indicates FollowReferences
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 JvmtiTagMap* _tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 Handle _initial_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 GrowableArray<oop>* _visit_stack; // the visit stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2695
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 bool _collecting_heap_roots; // are we collecting roots
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 bool _following_object_refs; // are we following object references
a61af66fc99e Initial load
duke
parents:
diff changeset
2698
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 bool _reporting_primitive_fields; // optional reporting
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 bool _reporting_primitive_array_values;
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 bool _reporting_string_values;
a61af66fc99e Initial load
duke
parents:
diff changeset
2702
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 GrowableArray<oop>* create_visit_stack() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 return new (ResourceObj::C_HEAP) GrowableArray<oop>(initial_visit_stack_size, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2706
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 JvmtiTagMap* tag_map() const { return _tag_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 Handle initial_object() const { return _initial_object; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2711
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 bool is_following_references() const { return _following_object_refs; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 bool is_reporting_primitive_fields() const { return _reporting_primitive_fields; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 bool is_reporting_string_values() const { return _reporting_string_values; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2717
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 GrowableArray<oop>* visit_stack() const { return _visit_stack; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2719
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 // iterate over the various object types
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 inline bool iterate_over_array(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 inline bool iterate_over_type_array(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 inline bool iterate_over_class(klassOop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 inline bool iterate_over_object(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2725
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 // root collection
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 inline bool collect_simple_roots();
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 inline bool collect_stack_roots();
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
2730
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 // visit an object
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 inline bool visit(oop o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2733
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 BasicHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 const void* user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
2739
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 AdvancedHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 const void* user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
2744
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 ~VM_HeapWalkOperation();
a61af66fc99e Initial load
duke
parents:
diff changeset
2746
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 VMOp_Type type() const { return VMOp_HeapWalkOperation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 void doit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2750
a61af66fc99e Initial load
duke
parents:
diff changeset
2751
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 BasicHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 _is_advanced_heap_walk = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 _initial_object = initial_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 _following_object_refs = (callbacks.object_ref_callback() != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 _reporting_primitive_fields = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 _reporting_primitive_array_values = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 _reporting_string_values = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 _visit_stack = create_visit_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
2764
a61af66fc99e Initial load
duke
parents:
diff changeset
2765
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks);
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2768
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 Handle initial_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 AdvancedHeapWalkContext callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 _is_advanced_heap_walk = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 _tag_map = tag_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 _initial_object = initial_object;
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 _following_object_refs = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 _visit_stack = create_visit_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
2781
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks);
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2784
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 VM_HeapWalkOperation::~VM_HeapWalkOperation() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 if (_following_object_refs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 assert(_visit_stack != NULL, "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 delete _visit_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 _visit_stack = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2792
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 // an array references its class and has a reference to
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 // each element in the array
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 objArrayOop array = objArrayOop(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 if (array->klass() == Universe::systemObjArrayKlassObj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 // filtered out
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2801
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 // array reference to its class
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 oop mirror = objArrayKlass::cast(array->klass())->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 if (!CallbackInvoker::report_class_reference(o, mirror)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2807
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 // iterate over the array and report each reference to a
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 // non-null element
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 for (int index=0; index<array->length(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 oop elem = array->obj_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 if (elem == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2815
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 // report the array reference o[index] = elem
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 if (!CallbackInvoker::report_array_element_reference(o, elem, index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2823
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // a type array references its class
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 klassOop k = o->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 oop mirror = Klass::cast(k)->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 if (!CallbackInvoker::report_class_reference(o, mirror)) {
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 // report the array contents if required
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 if (is_reporting_primitive_array_values()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 if (!CallbackInvoker::report_primitive_array_values(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2840
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 // 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
2842 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
2843 oop mirror, int offset) {
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2844 address obj_p = (address)mirror + offset;
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2177
diff changeset
2845 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
2846 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 assert(end >= start, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2848
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 if (obj_p >= start && obj_p < end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2855
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 // a class references its super class, interfaces, class loader, ...
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 // and finally its static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 Klass* klass = klassOop(k)->klass_part();
a61af66fc99e Initial load
duke
parents:
diff changeset
2861
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 if (klass->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 instanceKlass* ik = instanceKlass::cast(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
2864
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 // ignore the class if it's has been initialized yet
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 if (!ik->is_linked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2869
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 // get the java mirror
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 oop mirror = klass->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2872
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 // super (only if something more interesting than java.lang.Object)
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 klassOop java_super = ik->java_super();
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
2875 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 oop super = Klass::cast(java_super)->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2881
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 // class loader
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 oop cl = ik->class_loader();
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 if (cl != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2889
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 // protection domain
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 oop pd = ik->protection_domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 if (pd != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2897
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 // signers
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 oop signers = ik->signers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 if (signers != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 if (!CallbackInvoker::report_signers_reference(mirror, signers)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2905
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 // references from the constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 const constantPoolOop pool = ik->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 for (int i = 1; i < pool->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 constantTag tag = pool->tag_at(i).value();
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 if (tag.is_string() || tag.is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 oop entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 if (tag.is_string()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 entry = pool->resolved_string_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 assert(java_lang_String::is_instance(entry), "must be string");
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2925
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 // (These will already have been reported as references from the constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 // but are specified by IterateOverReachableObjects and must be reported).
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 objArrayOop interfaces = ik->local_interfaces();
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 for (i = 0; i < interfaces->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 oop interf = Klass::cast((klassOop)interfaces->obj_at(i))->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 if (interf == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 if (!CallbackInvoker::report_interface_reference(mirror, interf)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2939
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // iterate over the static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2941
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 for (i=0; i<field_map->field_count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 ClassFieldDescriptor* field = field_map->field_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 char type = field->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 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
2947 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
2948 assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 if (fld_o != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 if (is_reporting_primitive_fields()) {
2377
57552dca1708 7029509: nightly failures after static fields in Class
never
parents: 2376
diff changeset
2958 address addr = (address)mirror + field->field_offset();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 delete field_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2968
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2971
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2974
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 // an object references a class and its instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 // (static fields are ignored here as we report these as
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 // references from the class).
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 // reference to the class
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 if (!CallbackInvoker::report_class_reference(o, Klass::cast(o->klass())->java_mirror())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2983
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 // iterate over instance fields
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 for (int i=0; i<field_map->field_count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 ClassFieldDescriptor* field = field_map->field_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 char type = field->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 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
2990 oop fld_o = o->obj_field(field->field_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 if (fld_o != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 // reflection code may have a reference to a klassOop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 // - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 if (fld_o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 klassOop k = (klassOop)fld_o;
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 fld_o = Klass::cast(k)->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 if (is_reporting_primitive_fields()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 // primitive instance field
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 address addr = (address)o + field->field_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 int slot = field->field_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3014
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 // if the object is a java.lang.String
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 if (is_reporting_string_values() &&
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
3017 o->klass() == SystemDictionary::String_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 if (!CallbackInvoker::report_string_value(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 return true;
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 // collects all simple (non-stack) roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // if there's a heap root callback provided then the callback is
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 // invoked for each simple root.
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 // if an object reference callback is provided then all simple
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 // roots are pushed onto the marking stack so that they can be
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 // processed later
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 inline bool VM_HeapWalkOperation::collect_simple_roots() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 SimpleRootsClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
3035
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 // JNI globals
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 JNIHandles::oops_do(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 if (blk.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3042
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 // Preloaded classes and loader from the system dictionary
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 SystemDictionary::always_strong_oops_do(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 if (blk.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3049
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 // Inflated monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 ObjectSynchronizer::oops_do(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 if (blk.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3056
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 // Threads
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 oop threadObj = thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 if (!cont) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3067
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 // Other kinds of roots maintained by HotSpot
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 // Many of these won't be visible but others (such as instances of important
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 // exceptions) will be visible.
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 Universe::oops_do(&blk);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3073
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3074 // 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
3075 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3076 CodeBlobToOopClosure look_in_blobs(&blk, false);
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 579
diff changeset
3077 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
3078
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3081
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 // Walk the stack of a given thread and find all references (locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 // and JNI calls) and report these as stack references
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 JNILocalRootsClosure* blk)
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 oop threadObj = java_thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 assert(threadObj != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3089
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // only need to get the thread's tag once per thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 jlong thread_tag = tag_for(_tag_map, threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3092
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // also need the thread id
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 jlong tid = java_lang_Thread::thread_id(threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3095
a61af66fc99e Initial load
duke
parents:
diff changeset
3096
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 if (java_thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 // vframes are resource allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 Thread* current_thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 ResourceMark rm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 HandleMark hm(current_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3103
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 RegisterMap reg_map(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 frame f = java_thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3107
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 bool is_top_frame = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 int depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 frame* last_entry_frame = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3111
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 while (vf != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 if (vf->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3114
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 // java frame (interpreted, compiled, ...)
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 javaVFrame *jvf = javaVFrame::cast(vf);
a61af66fc99e Initial load
duke
parents:
diff changeset
3117
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 // the jmethodID
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 jmethodID method = jvf->method()->jmethod_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
3120
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 if (!(jvf->method()->is_native())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 jlocation bci = (jlocation)jvf->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 StackValueCollection* locals = jvf->locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 for (int slot=0; slot<locals->size(); slot++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 if (locals->at(slot)->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 oop o = locals->obj_at(slot)();
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 if (o == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3130
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 // stack reference
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method,
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 bci, slot, o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 blk->set_context(thread_tag, tid, depth, method);
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 if (is_top_frame) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 // JNI locals for the top frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 java_thread->active_handles()->oops_do(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 if (last_entry_frame != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 // JNI locals for the entry frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 assert(last_entry_frame->is_entry_frame(), "checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 last_entry_frame = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 // externalVFrame - for an entry frame then we report the JNI locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 // when we find the corresponding javaVFrame
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 frame* fr = vf->frame_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 assert(fr != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 if (fr->is_entry_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 last_entry_frame = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 }
3363
167b70ff3abc 6939861: JVM should handle more conversion operations
never
parents: 2377
diff changeset
3161 if (fr->is_ricochet_frame()) {
167b70ff3abc 6939861: JVM should handle more conversion operations
never
parents: 2377
diff changeset
3162 fr->oops_ricochet_do(blk, vf->register_map());
167b70ff3abc 6939861: JVM should handle more conversion operations
never
parents: 2377
diff changeset
3163 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3165
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 vf = vf->sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 is_top_frame = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 // no last java frame but there may be JNI locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 blk->set_context(thread_tag, tid, 0, (jmethodID)NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 java_thread->active_handles()->oops_do(blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3176
a61af66fc99e Initial load
duke
parents:
diff changeset
3177
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 // collects all stack roots - for each thread it walks the execution
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 // stack to find all references and local JNI refs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 inline bool VM_HeapWalkOperation::collect_stack_roots() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 JNILocalRootsClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 oop threadObj = thread->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 if (!collect_stack_roots(thread, &blk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3192
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 // visit an object
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 // first mark the object as visited
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 // second get all the outbound references from this object (in other words, all
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 // the objects referenced by this object).
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 bool VM_HeapWalkOperation::visit(oop o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 // mark object as visited
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 assert(!ObjectMarker::visited(o), "can't visit same object more than once");
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 ObjectMarker::mark(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3202
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 // instance
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 if (o->is_instance()) {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 989
diff changeset
3205 if (o->klass() == SystemDictionary::Class_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 o = klassOop_if_java_lang_Class(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 if (o->is_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 // a java.lang.Class
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 return iterate_over_class(klassOop(o));
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 return iterate_over_object(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3215
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 // object array
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 if (o->is_objArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 return iterate_over_array(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3220
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 // type array
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 if (o->is_typeArray()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 return iterate_over_type_array(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3225
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3228
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 void VM_HeapWalkOperation::doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 ObjectMarkerController marker;
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 ClassFieldMapCacheMark cm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3233
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 assert(visit_stack()->is_empty(), "visit stack must be empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
3235
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 // the heap walk starts with an initial object or the heap roots
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 if (initial_object().is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 if (!collect_simple_roots()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 if (!collect_stack_roots()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 visit_stack()->push(initial_object()());
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3243
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 // object references required
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 if (is_following_references()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3246
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 // visit each object until all reachable objects have been
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 // visited or the callback asked to terminate the iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 while (!visit_stack()->is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 oop o = visit_stack()->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 if (!ObjectMarker::visited(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 if (!visit(o)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3259
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 // iterate over all objects that are reachable from a set of roots
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 jvmtiStackReferenceCallback stack_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 jvmtiObjectReferenceCallback object_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 VM_HeapWalkOperation op(this, Handle(), context, user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3270
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 // iterate over all objects that are reachable from a given object
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 jvmtiObjectReferenceCallback object_ref_callback,
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 const void* user_data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 oop obj = JNIHandles::resolve(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 Handle initial_object(Thread::current(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3277
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 VM_HeapWalkOperation op(this, initial_object, context, user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3283
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 // follow references from an initial object or the GC roots
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 void JvmtiTagMap::follow_references(jint heap_filter,
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 KlassHandle klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 jobject object,
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 const jvmtiHeapCallbacks* callbacks,
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 const void* user_data)
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 oop obj = JNIHandles::resolve(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 Handle initial_object(Thread::current(), obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3293
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 VM_HeapWalkOperation op(this, initial_object, context, user_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3299
a61af66fc99e Initial load
duke
parents:
diff changeset
3300
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3301 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
3302 // 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
3303 // 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
3304 // 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
3305 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
3306 SafepointSynchronize::is_at_safepoint(),
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3307 "must be executed at a safepoint");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 if (JvmtiEnv::environments_might_exist()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 JvmtiEnvIterator it;
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 JvmtiTagMap* tag_map = env->tag_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 if (tag_map != NULL && !tag_map->is_empty()) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3313 tag_map->do_weak_oops(is_alive, f);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3318
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3319 void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3320
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 // does this environment have the OBJECT_FREE event enabled
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3323
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 // counters used for trace message
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 int freed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 int moved = 0;
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3327
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3328 JvmtiTagHashmap* hashmap = this->hashmap();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3329
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 // reenable sizing (if disabled)
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3331 hashmap->set_resizing_enabled(true);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3332
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3333 // 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
3334 if (hashmap->_entry_count == 0) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3335 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3337
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3338 // now iterate through each entry in the table
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3339
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3340 JvmtiTagHashmapEntry** table = hashmap->table();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3341 int size = hashmap->size();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3342
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3343 JvmtiTagHashmapEntry* delayed_add = NULL;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3344
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3345 for (int pos = 0; pos < size; ++pos) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3346 JvmtiTagHashmapEntry* entry = table[pos];
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3347 JvmtiTagHashmapEntry* prev = NULL;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3348
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3349 while (entry != NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3350 JvmtiTagHashmapEntry* next = entry->next();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3351
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3352 oop* obj = entry->object_addr();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3353
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3354 // has object been GC'ed
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3355 if (!is_alive->do_object_b(entry->object())) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3356 // grab the tag
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3357 jlong tag = entry->tag();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3358 guarantee(tag != 0, "checking");
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3359
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3360 // remove GC'ed entry from hashmap and return the
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3361 // entry to the free list
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3362 hashmap->remove(prev, pos, entry);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3363 destroy_entry(entry);
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 // post the event to the profiler
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3366 if (post_object_free) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3367 JvmtiExport::post_object_free(env(), tag);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3368 }
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3369
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3370 ++freed;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3371 } else {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3372 f->do_oop(entry->object_addr());
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3373 oop new_oop = entry->object();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3374
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3375 // 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
3376 // entry to its new location.
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3377 unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3378 if (new_pos != (unsigned int)pos) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3379 if (prev == NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3380 table[pos] = next;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3381 } else {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3382 prev->set_next(next);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3384 if (new_pos < (unsigned int)pos) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 entry->set_next(table[new_pos]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 table[new_pos] = entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 } else {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3388 // 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
3389 // hitting it again during this iteration.
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3390 entry->set_next(delayed_add);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3391 delayed_add = entry;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3393 moved++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 } else {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3395 // object didn't move
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3396 prev = entry;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 }
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3399
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3400 entry = next;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3403
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3404 // Re-add all the entries which were kept aside
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3405 while (delayed_add != NULL) {
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3406 JvmtiTagHashmapEntry* next = delayed_add->next();
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3407 unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3408 delayed_add->set_next(table[pos]);
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3409 table[pos] = delayed_add;
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3410 delayed_add = next;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3412
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 // stats
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 if (TraceJVMTIObjectTagging) {
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3415 int post_total = hashmap->_entry_count;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 int pre_total = post_total + freed;
a61af66fc99e Initial load
duke
parents:
diff changeset
3417
2125
7246a374a9f2 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 1972
diff changeset
3418 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
3419 pre_total, post_total, freed, moved);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 }