Mercurial > hg > graal-jvmci-8
annotate src/share/vm/oops/constantPoolOop.hpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | be93aad57795 |
children | 389049f3f393 |
rev | line source |
---|---|
0 | 1 /* |
579 | 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 // A constantPool is an array containing class constants as described in the | |
26 // class file. | |
27 // | |
28 // Most of the constant pool entries are written during class parsing, which | |
29 // is safe. For klass and string types, the constant pool entry is | |
30 // modified when the entry is resolved. If a klass or string constant pool | |
31 // entry is read without a lock, only the resolved state guarantees that | |
32 // the entry in the constant pool is a klass or String object and | |
33 // not a symbolOop. | |
34 | |
35 class SymbolHashMap; | |
36 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
37 class constantPoolOopDesc : public oopDesc { |
0 | 38 friend class VMStructs; |
39 friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast | |
40 private: | |
41 typeArrayOop _tags; // the tag array describing the constant pool's contents | |
42 constantPoolCacheOop _cache; // the cache holding interpreter runtime information | |
43 klassOop _pool_holder; // the corresponding class | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
44 int _flags; // a few header bits to describe contents for GC |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
45 int _length; // number of elements in the array |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
431
diff
changeset
|
46 volatile bool _is_conc_safe; // if true, safe for concurrent |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
431
diff
changeset
|
47 // GC processing |
0 | 48 // only set to non-zero if constant pool is merged by RedefineClasses |
49 int _orig_length; | |
50 | |
51 void set_tags(typeArrayOop tags) { oop_store_without_check((oop*)&_tags, tags); } | |
52 void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); } | |
53 void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); } | |
54 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
55 enum FlagBit { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
56 FB_has_invokedynamic = 1, |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
57 FB_has_pseudo_string = 2 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
58 }; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
59 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
60 int flags() const { return _flags; } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
61 void set_flags(int f) { _flags = f; } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
62 bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
63 void set_flag_at(FlagBit fb); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
64 // no clear_flag_at function; they only increase |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
65 |
0 | 66 private: |
67 intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); } | |
68 oop* tags_addr() { return (oop*)&_tags; } | |
69 oop* cache_addr() { return (oop*)&_cache; } | |
70 | |
71 oop* obj_at_addr(int which) const { | |
72 assert(is_within_bounds(which), "index out of bounds"); | |
73 return (oop*) &base()[which]; | |
74 } | |
75 | |
76 jint* int_at_addr(int which) const { | |
77 assert(is_within_bounds(which), "index out of bounds"); | |
78 return (jint*) &base()[which]; | |
79 } | |
80 | |
81 jlong* long_at_addr(int which) const { | |
82 assert(is_within_bounds(which), "index out of bounds"); | |
83 return (jlong*) &base()[which]; | |
84 } | |
85 | |
86 jfloat* float_at_addr(int which) const { | |
87 assert(is_within_bounds(which), "index out of bounds"); | |
88 return (jfloat*) &base()[which]; | |
89 } | |
90 | |
91 jdouble* double_at_addr(int which) const { | |
92 assert(is_within_bounds(which), "index out of bounds"); | |
93 return (jdouble*) &base()[which]; | |
94 } | |
95 | |
96 public: | |
97 typeArrayOop tags() const { return _tags; } | |
98 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
99 bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
100 bool has_invokedynamic() const { return flag_at(FB_has_invokedynamic); } |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
101 void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
102 void set_invokedynamic() { set_flag_at(FB_has_invokedynamic); } |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
103 |
0 | 104 // Klass holding pool |
105 klassOop pool_holder() const { return _pool_holder; } | |
106 void set_pool_holder(klassOop k) { oop_store_without_check((oop*)&_pool_holder, (oop) k); } | |
107 oop* pool_holder_addr() { return (oop*)&_pool_holder; } | |
108 | |
109 // Interpreter runtime support | |
110 constantPoolCacheOop cache() const { return _cache; } | |
111 void set_cache(constantPoolCacheOop cache){ oop_store((oop*)&_cache, cache); } | |
112 | |
113 // Assembly code support | |
114 static int tags_offset_in_bytes() { return offset_of(constantPoolOopDesc, _tags); } | |
115 static int cache_offset_in_bytes() { return offset_of(constantPoolOopDesc, _cache); } | |
116 static int pool_holder_offset_in_bytes() { return offset_of(constantPoolOopDesc, _pool_holder); } | |
117 | |
118 // Storing constants | |
119 | |
120 void klass_at_put(int which, klassOop k) { | |
121 oop_store_without_check((volatile oop *)obj_at_addr(which), oop(k)); | |
122 // The interpreter assumes when the tag is stored, the klass is resolved | |
123 // and the klassOop is a klass rather than a symbolOop, so we need | |
124 // hardware store ordering here. | |
125 release_tag_at_put(which, JVM_CONSTANT_Class); | |
126 if (UseConcMarkSweepGC) { | |
127 // In case the earlier card-mark was consumed by a concurrent | |
128 // marking thread before the tag was updated, redirty the card. | |
129 oop_store_without_check((volatile oop *)obj_at_addr(which), oop(k)); | |
130 } | |
131 } | |
132 | |
133 // For temporary use while constructing constant pool | |
134 void klass_index_at_put(int which, int name_index) { | |
135 tag_at_put(which, JVM_CONSTANT_ClassIndex); | |
136 *int_at_addr(which) = name_index; | |
137 } | |
138 | |
139 // Temporary until actual use | |
140 void unresolved_klass_at_put(int which, symbolOop s) { | |
141 // Overwrite the old index with a GC friendly value so | |
142 // that if GC looks during the transition it won't try | |
143 // to treat a small integer as oop. | |
144 *obj_at_addr(which) = NULL; | |
145 release_tag_at_put(which, JVM_CONSTANT_UnresolvedClass); | |
146 oop_store_without_check(obj_at_addr(which), oop(s)); | |
147 } | |
148 | |
149 // Temporary until actual use | |
150 void unresolved_string_at_put(int which, symbolOop s) { | |
151 *obj_at_addr(which) = NULL; | |
152 release_tag_at_put(which, JVM_CONSTANT_UnresolvedString); | |
153 oop_store_without_check(obj_at_addr(which), oop(s)); | |
154 } | |
155 | |
156 void int_at_put(int which, jint i) { | |
157 tag_at_put(which, JVM_CONSTANT_Integer); | |
158 *int_at_addr(which) = i; | |
159 } | |
160 | |
161 void long_at_put(int which, jlong l) { | |
162 tag_at_put(which, JVM_CONSTANT_Long); | |
163 // *long_at_addr(which) = l; | |
164 Bytes::put_native_u8((address)long_at_addr(which), *((u8*) &l)); | |
165 } | |
166 | |
167 void float_at_put(int which, jfloat f) { | |
168 tag_at_put(which, JVM_CONSTANT_Float); | |
169 *float_at_addr(which) = f; | |
170 } | |
171 | |
172 void double_at_put(int which, jdouble d) { | |
173 tag_at_put(which, JVM_CONSTANT_Double); | |
174 // *double_at_addr(which) = d; | |
175 // u8 temp = *(u8*) &d; | |
176 Bytes::put_native_u8((address) double_at_addr(which), *((u8*) &d)); | |
177 } | |
178 | |
179 void symbol_at_put(int which, symbolOop s) { | |
180 tag_at_put(which, JVM_CONSTANT_Utf8); | |
181 oop_store_without_check(obj_at_addr(which), oop(s)); | |
182 } | |
183 | |
184 void string_at_put(int which, oop str) { | |
185 oop_store((volatile oop*)obj_at_addr(which), str); | |
186 release_tag_at_put(which, JVM_CONSTANT_String); | |
187 if (UseConcMarkSweepGC) { | |
188 // In case the earlier card-mark was consumed by a concurrent | |
189 // marking thread before the tag was updated, redirty the card. | |
190 oop_store_without_check((volatile oop *)obj_at_addr(which), str); | |
191 } | |
192 } | |
193 | |
194 // For temporary use while constructing constant pool | |
195 void string_index_at_put(int which, int string_index) { | |
196 tag_at_put(which, JVM_CONSTANT_StringIndex); | |
197 *int_at_addr(which) = string_index; | |
198 } | |
199 | |
200 void field_at_put(int which, int class_index, int name_and_type_index) { | |
201 tag_at_put(which, JVM_CONSTANT_Fieldref); | |
202 *int_at_addr(which) = ((jint) name_and_type_index<<16) | class_index; | |
203 } | |
204 | |
205 void method_at_put(int which, int class_index, int name_and_type_index) { | |
206 tag_at_put(which, JVM_CONSTANT_Methodref); | |
207 *int_at_addr(which) = ((jint) name_and_type_index<<16) | class_index; | |
208 } | |
209 | |
210 void interface_method_at_put(int which, int class_index, int name_and_type_index) { | |
211 tag_at_put(which, JVM_CONSTANT_InterfaceMethodref); | |
212 *int_at_addr(which) = ((jint) name_and_type_index<<16) | class_index; // Not so nice | |
213 } | |
214 | |
215 void name_and_type_at_put(int which, int name_index, int signature_index) { | |
216 tag_at_put(which, JVM_CONSTANT_NameAndType); | |
217 *int_at_addr(which) = ((jint) signature_index<<16) | name_index; // Not so nice | |
218 } | |
219 | |
220 // Tag query | |
221 | |
222 constantTag tag_at(int which) const { return (constantTag)tags()->byte_at_acquire(which); } | |
223 | |
224 // Whether the entry is a pointer that must be GC'd. | |
225 bool is_pointer_entry(int which) { | |
226 constantTag tag = tag_at(which); | |
227 return tag.is_klass() || | |
228 tag.is_unresolved_klass() || | |
229 tag.is_symbol() || | |
230 tag.is_unresolved_string() || | |
231 tag.is_string(); | |
232 } | |
233 | |
234 // Fetching constants | |
235 | |
236 klassOop klass_at(int which, TRAPS) { | |
237 constantPoolHandle h_this(THREAD, this); | |
238 return klass_at_impl(h_this, which, CHECK_NULL); | |
239 } | |
240 | |
241 symbolOop klass_name_at(int which); // Returns the name, w/o resolving. | |
242 | |
243 klassOop resolved_klass_at(int which) { // Used by Compiler | |
244 guarantee(tag_at(which).is_klass(), "Corrupted constant pool"); | |
245 // Must do an acquire here in case another thread resolved the klass | |
246 // behind our back, lest we later load stale values thru the oop. | |
247 return klassOop((oop)OrderAccess::load_ptr_acquire(obj_at_addr(which))); | |
248 } | |
249 | |
250 // This method should only be used with a cpool lock or during parsing or gc | |
251 symbolOop unresolved_klass_at(int which) { // Temporary until actual use | |
252 symbolOop s = symbolOop((oop)OrderAccess::load_ptr_acquire(obj_at_addr(which))); | |
253 // check that the klass is still unresolved. | |
254 assert(tag_at(which).is_unresolved_klass(), "Corrupted constant pool"); | |
255 return s; | |
256 } | |
257 | |
258 // RedefineClasses() API support: | |
259 symbolOop klass_at_noresolve(int which) { return klass_name_at(which); } | |
260 | |
261 jint int_at(int which) { | |
262 assert(tag_at(which).is_int(), "Corrupted constant pool"); | |
263 return *int_at_addr(which); | |
264 } | |
265 | |
266 jlong long_at(int which) { | |
267 assert(tag_at(which).is_long(), "Corrupted constant pool"); | |
268 // return *long_at_addr(which); | |
269 u8 tmp = Bytes::get_native_u8((address)&base()[which]); | |
270 return *((jlong*)&tmp); | |
271 } | |
272 | |
273 jfloat float_at(int which) { | |
274 assert(tag_at(which).is_float(), "Corrupted constant pool"); | |
275 return *float_at_addr(which); | |
276 } | |
277 | |
278 jdouble double_at(int which) { | |
279 assert(tag_at(which).is_double(), "Corrupted constant pool"); | |
280 u8 tmp = Bytes::get_native_u8((address)&base()[which]); | |
281 return *((jdouble*)&tmp); | |
282 } | |
283 | |
284 symbolOop symbol_at(int which) { | |
285 assert(tag_at(which).is_utf8(), "Corrupted constant pool"); | |
286 return symbolOop(*obj_at_addr(which)); | |
287 } | |
288 | |
289 oop string_at(int which, TRAPS) { | |
290 constantPoolHandle h_this(THREAD, this); | |
291 return string_at_impl(h_this, which, CHECK_NULL); | |
292 } | |
293 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
294 // A "pseudo-string" is an non-string oop that has found is way into |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
295 // a String entry. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
296 // Under AnonymousClasses this can happen if the user patches a live |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
297 // object into a CONSTANT_String entry of an anonymous class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
298 // Method oops internally created for method handles may also |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
299 // use pseudo-strings to link themselves to related metaobjects. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
300 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
301 bool is_pseudo_string_at(int which); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
302 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
303 oop pseudo_string_at(int which) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
304 assert(tag_at(which).is_string(), "Corrupted constant pool"); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
305 return *obj_at_addr(which); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
306 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
307 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
308 void pseudo_string_at_put(int which, oop x) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
309 assert(AnonymousClasses, ""); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
310 set_pseudo_string(); // mark header |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
311 assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool"); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
312 string_at_put(which, x); // this works just fine |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
313 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
314 |
0 | 315 // only called when we are sure a string entry is already resolved (via an |
316 // earlier string_at call. | |
317 oop resolved_string_at(int which) { | |
318 assert(tag_at(which).is_string(), "Corrupted constant pool"); | |
319 // Must do an acquire here in case another thread resolved the klass | |
320 // behind our back, lest we later load stale values thru the oop. | |
321 return (oop)OrderAccess::load_ptr_acquire(obj_at_addr(which)); | |
322 } | |
323 | |
324 // This method should only be used with a cpool lock or during parsing or gc | |
325 symbolOop unresolved_string_at(int which) { // Temporary until actual use | |
326 symbolOop s = symbolOop((oop)OrderAccess::load_ptr_acquire(obj_at_addr(which))); | |
327 // check that the string is still unresolved. | |
328 assert(tag_at(which).is_unresolved_string(), "Corrupted constant pool"); | |
329 return s; | |
330 } | |
331 | |
332 // Returns an UTF8 for a CONSTANT_String entry at a given index. | |
333 // UTF8 char* representation was chosen to avoid conversion of | |
334 // java_lang_Strings at resolved entries into symbolOops | |
335 // or vice versa. | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
336 // Caller is responsible for checking for pseudo-strings. |
0 | 337 char* string_at_noresolve(int which); |
338 | |
339 jint name_and_type_at(int which) { | |
340 assert(tag_at(which).is_name_and_type(), "Corrupted constant pool"); | |
341 return *int_at_addr(which); | |
342 } | |
343 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
344 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
345 // name_and_type_ref_index_at) all expect constant pool indices |
0 | 346 // from the bytecodes to be passed in, which are actually potentially byte-swapped |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
347 // or rewritten constant pool cache indices. They all call map_instruction_operand_to_index. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
348 int map_instruction_operand_to_index(int operand); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
349 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
350 // There are also "uncached" versions which do not map the operand index; see below. |
0 | 351 |
352 // Lookup for entries consisting of (klass_index, name_and_type index) | |
353 klassOop klass_ref_at(int which, TRAPS); | |
354 symbolOop klass_ref_at_noresolve(int which); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
355 symbolOop name_ref_at(int which) { return impl_name_ref_at(which, false); } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
356 symbolOop signature_ref_at(int which) { return impl_signature_ref_at(which, false); } |
0 | 357 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
358 int klass_ref_index_at(int which) { return impl_klass_ref_index_at(which, false); } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
359 int name_and_type_ref_index_at(int which) { return impl_name_and_type_ref_index_at(which, false); } |
0 | 360 |
361 // Lookup for entries consisting of (name_index, signature_index) | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
362 int name_ref_index_at(int which_nt); // == low-order jshort of name_and_type_at(which_nt) |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
363 int signature_ref_index_at(int which_nt); // == high-order jshort of name_and_type_at(which_nt) |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
364 symbolOop nt_name_ref_at(int which_nt) { return symbol_at(name_ref_index_at(which_nt)); } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
365 symbolOop nt_signature_ref_at(int which_nt) { return symbol_at(signature_ref_index_at(which_nt)); } |
0 | 366 |
367 BasicType basic_type_for_signature_at(int which); | |
368 | |
369 // Resolve string constants (to prevent allocation during compilation) | |
370 void resolve_string_constants(TRAPS) { | |
371 constantPoolHandle h_this(THREAD, this); | |
372 resolve_string_constants_impl(h_this, CHECK); | |
373 } | |
374 | |
375 // Klass name matches name at offset | |
376 bool klass_name_at_matches(instanceKlassHandle k, int which); | |
377 | |
378 // Sizing | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
379 int length() const { return _length; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
380 void set_length(int length) { _length = length; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
381 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
382 // Tells whether index is within bounds. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
383 bool is_within_bounds(int index) const { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
384 return 0 <= index && index < length(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
385 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
386 |
0 | 387 static int header_size() { return sizeof(constantPoolOopDesc)/HeapWordSize; } |
388 static int object_size(int length) { return align_object_size(header_size() + length); } | |
389 int object_size() { return object_size(length()); } | |
390 | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
431
diff
changeset
|
391 bool is_conc_safe() { return _is_conc_safe; } |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
431
diff
changeset
|
392 void set_is_conc_safe(bool v) { _is_conc_safe = v; } |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
431
diff
changeset
|
393 |
0 | 394 friend class constantPoolKlass; |
395 friend class ClassFileParser; | |
396 friend class SystemDictionary; | |
397 | |
398 // Used by compiler to prevent classloading. | |
399 static klassOop klass_at_if_loaded (constantPoolHandle this_oop, int which); | |
400 static klassOop klass_ref_at_if_loaded (constantPoolHandle this_oop, int which); | |
401 // Same as above - but does LinkResolving. | |
402 static klassOop klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS); | |
403 | |
404 // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the | |
405 // future by other Java code. These take constant pool indices rather than possibly-byte-swapped | |
406 // constant pool cache indices as do the peer methods above. | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
407 symbolOop uncached_name_ref_at(int which) { return impl_name_ref_at(which, true); } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
408 symbolOop uncached_signature_ref_at(int which) { return impl_signature_ref_at(which, true); } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
409 int uncached_klass_ref_index_at(int which) { return impl_klass_ref_index_at(which, true); } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
410 int uncached_name_and_type_ref_index_at(int which) { return impl_name_and_type_ref_index_at(which, true); } |
0 | 411 |
412 // Sharing | |
413 int pre_resolve_shared_klasses(TRAPS); | |
414 void shared_symbols_iterate(OopClosure* closure0); | |
415 void shared_tags_iterate(OopClosure* closure0); | |
416 void shared_strings_iterate(OopClosure* closure0); | |
417 | |
418 // Debugging | |
419 const char* printable_name_at(int which) PRODUCT_RETURN0; | |
420 | |
421 private: | |
422 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
423 symbolOop impl_name_ref_at(int which, bool uncached); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
424 symbolOop impl_signature_ref_at(int which, bool uncached); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
425 int impl_klass_ref_index_at(int which, bool uncached); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
426 int impl_name_and_type_ref_index_at(int which, bool uncached); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
427 |
0 | 428 // Takes either a constant pool cache index in possibly byte-swapped |
429 // byte order (which comes from the bytecodes after rewriting) or, | |
430 // if "uncached" is true, a vanilla constant pool index | |
431 jint field_or_method_at(int which, bool uncached) { | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
432 int i = which; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
433 if (!uncached && cache() != NULL) { |
0 | 434 // change byte-ordering and go via cache |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
435 i = map_instruction_operand_to_index(which); |
0 | 436 } |
437 assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); | |
438 return *int_at_addr(i); | |
439 } | |
440 | |
441 // Used while constructing constant pool (only by ClassFileParser) | |
442 jint klass_index_at(int which) { | |
443 assert(tag_at(which).is_klass_index(), "Corrupted constant pool"); | |
444 return *int_at_addr(which); | |
445 } | |
446 | |
447 jint string_index_at(int which) { | |
448 assert(tag_at(which).is_string_index(), "Corrupted constant pool"); | |
449 return *int_at_addr(which); | |
450 } | |
451 | |
452 // Performs the LinkResolver checks | |
453 static void verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle klass, TRAPS); | |
454 | |
455 // Implementation of methods that needs an exposed 'this' pointer, in order to | |
456 // handle GC while executing the method | |
457 static klassOop klass_at_impl(constantPoolHandle this_oop, int which, TRAPS); | |
458 static oop string_at_impl(constantPoolHandle this_oop, int which, TRAPS); | |
459 | |
460 // Resolve string constants (to prevent allocation during compilation) | |
461 static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS); | |
462 | |
463 public: | |
464 // Merging constantPoolOop support: | |
465 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS); | |
466 void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, | |
467 TRAPS); | |
468 void copy_entry_to(int from_i, constantPoolHandle to_cp, int to_i, TRAPS); | |
469 int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); | |
470 int orig_length() const { return _orig_length; } | |
471 void set_orig_length(int orig_length) { _orig_length = orig_length; } | |
472 | |
473 | |
474 // JVMTI accesss - GetConstantPool, RetransformClasses, ... | |
475 friend class JvmtiConstantPoolReconstituter; | |
476 | |
477 private: | |
478 jint cpool_entry_size(jint idx); | |
479 jint hash_entries_to(SymbolHashMap *symmap, SymbolHashMap *classmap); | |
480 | |
481 // Copy cpool bytes into byte array. | |
482 // Returns: | |
483 // int > 0, count of the raw cpool bytes that have been copied | |
484 // 0, OutOfMemory error | |
485 // -1, Internal error | |
486 int copy_cpool_bytes(int cpool_size, | |
487 SymbolHashMap* tbl, | |
488 unsigned char *bytes); | |
489 }; | |
490 | |
491 class SymbolHashMapEntry : public CHeapObj { | |
492 private: | |
493 unsigned int _hash; // 32-bit hash for item | |
494 SymbolHashMapEntry* _next; // Next element in the linked list for this bucket | |
495 symbolOop _symbol; // 1-st part of the mapping: symbol => value | |
496 u2 _value; // 2-nd part of the mapping: symbol => value | |
497 | |
498 public: | |
499 unsigned int hash() const { return _hash; } | |
500 void set_hash(unsigned int hash) { _hash = hash; } | |
501 | |
502 SymbolHashMapEntry* next() const { return _next; } | |
503 void set_next(SymbolHashMapEntry* next) { _next = next; } | |
504 | |
505 symbolOop symbol() const { return _symbol; } | |
506 void set_symbol(symbolOop sym) { _symbol = sym; } | |
507 | |
508 u2 value() const { return _value; } | |
509 void set_value(u2 value) { _value = value; } | |
510 | |
511 SymbolHashMapEntry(unsigned int hash, symbolOop symbol, u2 value) | |
512 : _hash(hash), _symbol(symbol), _value(value), _next(NULL) {} | |
513 | |
514 }; // End SymbolHashMapEntry class | |
515 | |
516 | |
517 class SymbolHashMapBucket : public CHeapObj { | |
518 | |
519 private: | |
520 SymbolHashMapEntry* _entry; | |
521 | |
522 public: | |
523 SymbolHashMapEntry* entry() const { return _entry; } | |
524 void set_entry(SymbolHashMapEntry* entry) { _entry = entry; } | |
525 void clear() { _entry = NULL; } | |
526 | |
527 }; // End SymbolHashMapBucket class | |
528 | |
529 | |
530 class SymbolHashMap: public CHeapObj { | |
531 | |
532 private: | |
533 // Default number of entries in the table | |
534 enum SymbolHashMap_Constants { | |
535 _Def_HashMap_Size = 256 | |
536 }; | |
537 | |
538 int _table_size; | |
539 SymbolHashMapBucket* _buckets; | |
540 | |
541 void initialize_table(int table_size) { | |
542 _table_size = table_size; | |
543 _buckets = NEW_C_HEAP_ARRAY(SymbolHashMapBucket, table_size); | |
544 for (int index = 0; index < table_size; index++) { | |
545 _buckets[index].clear(); | |
546 } | |
547 } | |
548 | |
549 public: | |
550 | |
551 int table_size() const { return _table_size; } | |
552 | |
553 SymbolHashMap() { initialize_table(_Def_HashMap_Size); } | |
554 SymbolHashMap(int table_size) { initialize_table(table_size); } | |
555 | |
556 // hash P(31) from Kernighan & Ritchie | |
557 static unsigned int compute_hash(const char* str, int len) { | |
558 unsigned int hash = 0; | |
559 while (len-- > 0) { | |
560 hash = 31*hash + (unsigned) *str; | |
561 str++; | |
562 } | |
563 return hash; | |
564 } | |
565 | |
566 SymbolHashMapEntry* bucket(int i) { | |
567 return _buckets[i].entry(); | |
568 } | |
569 | |
570 void add_entry(symbolOop sym, u2 value); | |
571 SymbolHashMapEntry* find_entry(symbolOop sym); | |
572 | |
573 u2 symbol_to_value(symbolOop sym) { | |
574 SymbolHashMapEntry *entry = find_entry(sym); | |
575 return (entry == NULL) ? 0 : entry->value(); | |
576 } | |
577 | |
578 ~SymbolHashMap() { | |
579 SymbolHashMapEntry* next; | |
580 for (int i = 0; i < _table_size; i++) { | |
581 for (SymbolHashMapEntry* cur = bucket(i); cur != NULL; cur = next) { | |
582 next = cur->next(); | |
583 delete(cur); | |
584 } | |
585 } | |
586 delete _buckets; | |
587 } | |
588 }; // End SymbolHashMap class |