Mercurial > hg > truffle
annotate src/share/vm/ci/ciField.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 | c7f3d0b4570f |
children | 0654ee04b214 81d815b05abb |
rev | line source |
---|---|
0 | 1 /* |
2261 | 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1173
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1173
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:
1173
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/ciField.hpp" | |
27 #include "ci/ciInstanceKlass.hpp" | |
28 #include "ci/ciUtilities.hpp" | |
29 #include "classfile/systemDictionary.hpp" | |
30 #include "gc_interface/collectedHeap.inline.hpp" | |
31 #include "interpreter/linkResolver.hpp" | |
32 #include "memory/universe.inline.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 #include "oops/oop.inline2.hpp" | |
35 #include "runtime/fieldDescriptor.hpp" | |
0 | 36 |
37 // ciField | |
38 // | |
39 // This class represents the result of a field lookup in the VM. | |
40 // The lookup may not succeed, in which case the information in | |
41 // the ciField will be incomplete. | |
42 | |
43 // The ciObjectFactory cannot create circular data structures in one query. | |
44 // To avoid vicious circularities, we initialize ciField::_type to NULL | |
45 // for reference types and derive it lazily from the ciField::_signature. | |
46 // Primitive types are eagerly initialized, and basic layout queries | |
47 // can succeed without initialization, using only the BasicType of the field. | |
48 | |
49 // Notes on bootstrapping and shared CI objects: A field is shared if and | |
50 // only if it is (a) non-static and (b) declared by a shared instance klass. | |
51 // This allows non-static field lists to be cached on shared types. | |
52 // Because the _type field is lazily initialized, however, there is a | |
53 // special restriction that a shared field cannot cache an unshared type. | |
54 // This puts a small performance penalty on shared fields with unshared | |
55 // types, such as StackTraceElement[] Throwable.stackTrace. | |
56 // (Throwable is shared because ClassCastException is shared, but | |
57 // StackTraceElement is not presently shared.) | |
58 | |
59 // It is not a vicious circularity for a ciField to recursively create | |
60 // the ciSymbols necessary to represent its name and signature. | |
61 // Therefore, these items are created eagerly, and the name and signature | |
62 // of a shared field are themselves shared symbols. This somewhat | |
63 // pollutes the set of shared CI objects: It grows from 50 to 93 items, | |
64 // with all of the additional 43 being uninteresting shared ciSymbols. | |
65 // This adds at most one step to the binary search, an amount which | |
66 // decreases for complex compilation tasks. | |
67 | |
68 // ------------------------------------------------------------------ | |
69 // ciField::ciField | |
70 ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with(NULL) { | |
71 ASSERT_IN_VM; | |
72 CompilerThread *thread = CompilerThread::current(); | |
73 | |
74 assert(ciObjectFactory::is_initialized(), "not a shared field"); | |
75 | |
76 assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool"); | |
77 | |
78 _cp_index = index; | |
79 constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); | |
80 | |
81 // Get the field's name, signature, and type. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
82 Symbol* name = cpool->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
83 _name = ciEnv::current(thread)->get_symbol(name); |
0 | 84 |
85 int nt_index = cpool->name_and_type_ref_index_at(index); | |
86 int sig_index = cpool->signature_ref_index_at(nt_index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
87 Symbol* signature = cpool->symbol_at(sig_index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
88 _signature = ciEnv::current(thread)->get_symbol(signature); |
0 | 89 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
90 BasicType field_type = FieldType::basic_type(signature); |
0 | 91 |
92 // If the field is a pointer type, get the klass of the | |
93 // field. | |
94 if (field_type == T_OBJECT || field_type == T_ARRAY) { | |
95 bool ignore; | |
96 // This is not really a class reference; the index always refers to the | |
97 // field's type signature, as a symbol. Linkage checks do not apply. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
98 _type = ciEnv::current(thread)->get_klass_by_index(cpool, sig_index, ignore, klass); |
0 | 99 } else { |
100 _type = ciType::make(field_type); | |
101 } | |
102 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
103 _name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name); |
0 | 104 |
105 // Get the field's declared holder. | |
106 // | |
107 // Note: we actually create a ciInstanceKlass for this klass, | |
108 // even though we may not need to. | |
109 int holder_index = cpool->klass_ref_index_at(index); | |
110 bool holder_is_accessible; | |
111 ciInstanceKlass* declared_holder = | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
112 ciEnv::current(thread)->get_klass_by_index(cpool, holder_index, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
113 holder_is_accessible, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
114 klass)->as_instance_klass(); |
0 | 115 |
116 // The declared holder of this field may not have been loaded. | |
117 // Bail out with partial field information. | |
118 if (!holder_is_accessible) { | |
119 // _cp_index and _type have already been set. | |
120 // The default values for _flags and _constant_value will suffice. | |
121 // We need values for _holder, _offset, and _is_constant, | |
122 _holder = declared_holder; | |
123 _offset = -1; | |
124 _is_constant = false; | |
125 return; | |
126 } | |
127 | |
128 instanceKlass* loaded_decl_holder = declared_holder->get_instanceKlass(); | |
129 | |
130 // Perform the field lookup. | |
131 fieldDescriptor field_desc; | |
132 klassOop canonical_holder = | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
133 loaded_decl_holder->find_field(name, signature, &field_desc); |
0 | 134 if (canonical_holder == NULL) { |
135 // Field lookup failed. Will be detected by will_link. | |
136 _holder = declared_holder; | |
137 _offset = -1; | |
138 _is_constant = false; | |
139 return; | |
140 } | |
141 | |
142 assert(canonical_holder == field_desc.field_holder(), "just checking"); | |
143 initialize_from(&field_desc); | |
144 } | |
145 | |
146 ciField::ciField(fieldDescriptor *fd): _known_to_link_with(NULL) { | |
147 ASSERT_IN_VM; | |
148 | |
149 _cp_index = -1; | |
150 | |
151 // Get the field's name, signature, and type. | |
152 ciEnv* env = CURRENT_ENV; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
153 _name = env->get_symbol(fd->name()); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
154 _signature = env->get_symbol(fd->signature()); |
0 | 155 |
156 BasicType field_type = fd->field_type(); | |
157 | |
158 // If the field is a pointer type, get the klass of the | |
159 // field. | |
160 if (field_type == T_OBJECT || field_type == T_ARRAY) { | |
161 _type = NULL; // must call compute_type on first access | |
162 } else { | |
163 _type = ciType::make(field_type); | |
164 } | |
165 | |
166 initialize_from(fd); | |
167 | |
168 // Either (a) it is marked shared, or else (b) we are done bootstrapping. | |
169 assert(is_shared() || ciObjectFactory::is_initialized(), | |
170 "bootstrap classes must not create & cache unshared fields"); | |
171 } | |
172 | |
1173
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
173 static bool trust_final_non_static_fields(ciInstanceKlass* holder) { |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
174 if (holder == NULL) |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
175 return false; |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
176 if (holder->name() == ciSymbol::java_lang_System()) |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
177 // Never trust strangely unstable finals: System.out, etc. |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
178 return false; |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
179 // Even if general trusting is disabled, trust system-built closures in these packages. |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2261
diff
changeset
|
180 if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke")) |
1173
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
181 return true; |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
182 return TrustFinalNonStaticFields; |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
183 } |
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
184 |
0 | 185 void ciField::initialize_from(fieldDescriptor* fd) { |
186 // Get the flags, offset, and canonical holder of the field. | |
187 _flags = ciFlags(fd->access_flags()); | |
188 _offset = fd->offset(); | |
189 _holder = CURRENT_ENV->get_object(fd->field_holder())->as_instance_klass(); | |
190 | |
191 // Check to see if the field is constant. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
192 if (_holder->is_initialized() && this->is_final()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
193 if (!this->is_static()) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2261
diff
changeset
|
194 // A field can be constant if it's a final static field or if |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2261
diff
changeset
|
195 // it's a final non-static field of a trusted class (classes in |
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2261
diff
changeset
|
196 // java.lang.invoke and sun.invoke packages and subpackages). |
1173
73b22f919c34
6912065: final fields in objects need to support inlining optimizations for JSR 292
jrose
parents:
1142
diff
changeset
|
197 if (trust_final_non_static_fields(_holder)) { |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
198 _is_constant = true; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
199 return; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
200 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
201 _is_constant = false; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
202 return; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
203 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
0
diff
changeset
|
204 |
0 | 205 // This field just may be constant. The only cases where it will |
206 // not be constant are: | |
207 // | |
208 // 1. The field holds a non-perm-space oop. The field is, strictly | |
209 // speaking, constant but we cannot embed non-perm-space oops into | |
210 // generated code. For the time being we need to consider the | |
211 // field to be not constant. | |
212 // 2. The field is a *special* static&final field whose value | |
213 // may change. The three examples are java.lang.System.in, | |
214 // java.lang.System.out, and java.lang.System.err. | |
215 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
216 KlassHandle k = _holder->get_klassOop(); |
1142 | 217 assert( SystemDictionary::System_klass() != NULL, "Check once per vm"); |
2261 | 218 if( k() == SystemDictionary::System_klass() ) { |
0 | 219 // Check offsets for case 2: System.in, System.out, or System.err |
220 if( _offset == java_lang_System::in_offset_in_bytes() || | |
221 _offset == java_lang_System::out_offset_in_bytes() || | |
222 _offset == java_lang_System::err_offset_in_bytes() ) { | |
223 _is_constant = false; | |
224 return; | |
225 } | |
226 } | |
227 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
228 Handle mirror = k->java_mirror(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
229 |
0 | 230 _is_constant = true; |
231 switch(type()->basic_type()) { | |
232 case T_BYTE: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
233 _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset)); |
0 | 234 break; |
235 case T_CHAR: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
236 _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset)); |
0 | 237 break; |
238 case T_SHORT: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
239 _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset)); |
0 | 240 break; |
241 case T_BOOLEAN: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
242 _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset)); |
0 | 243 break; |
244 case T_INT: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
245 _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset)); |
0 | 246 break; |
247 case T_FLOAT: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
248 _constant_value = ciConstant(mirror->float_field(_offset)); |
0 | 249 break; |
250 case T_DOUBLE: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
251 _constant_value = ciConstant(mirror->double_field(_offset)); |
0 | 252 break; |
253 case T_LONG: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
254 _constant_value = ciConstant(mirror->long_field(_offset)); |
0 | 255 break; |
256 case T_OBJECT: | |
257 case T_ARRAY: | |
258 { | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
259 oop o = mirror->obj_field(_offset); |
0 | 260 |
261 // A field will be "constant" if it is known always to be | |
262 // a non-null reference to an instance of a particular class, | |
263 // or to a particular array. This can happen even if the instance | |
264 // or array is not perm. In such a case, an "unloaded" ciArray | |
265 // or ciInstance is created. The compiler may be able to use | |
266 // information about the object's class (which is exact) or length. | |
267 | |
268 if (o == NULL) { | |
269 _constant_value = ciConstant(type()->basic_type(), ciNullObject::make()); | |
270 } else { | |
271 _constant_value = ciConstant(type()->basic_type(), CURRENT_ENV->get_object(o)); | |
272 assert(_constant_value.as_object() == CURRENT_ENV->get_object(o), "check interning"); | |
273 } | |
274 } | |
275 } | |
276 } else { | |
277 _is_constant = false; | |
278 } | |
279 } | |
280 | |
281 // ------------------------------------------------------------------ | |
282 // ciField::compute_type | |
283 // | |
284 // Lazily compute the type, if it is an instance klass. | |
285 ciType* ciField::compute_type() { | |
286 GUARDED_VM_ENTRY(return compute_type_impl();) | |
287 } | |
288 | |
289 ciType* ciField::compute_type_impl() { | |
290 ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(_holder, _signature, false); | |
291 if (!type->is_primitive_type() && is_shared()) { | |
292 // We must not cache a pointer to an unshared type, in a shared field. | |
293 bool type_is_also_shared = false; | |
294 if (type->is_type_array_klass()) { | |
295 type_is_also_shared = true; // int[] etc. are explicitly bootstrapped | |
296 } else if (type->is_instance_klass()) { | |
297 type_is_also_shared = type->as_instance_klass()->is_shared(); | |
298 } else { | |
299 // Currently there is no 'shared' query for array types. | |
300 type_is_also_shared = !ciObjectFactory::is_initialized(); | |
301 } | |
302 if (!type_is_also_shared) | |
303 return type; // Bummer. | |
304 } | |
305 _type = type; | |
306 return type; | |
307 } | |
308 | |
309 | |
310 // ------------------------------------------------------------------ | |
311 // ciField::will_link | |
312 // | |
313 // Can a specific access to this field be made without causing | |
314 // link errors? | |
315 bool ciField::will_link(ciInstanceKlass* accessing_klass, | |
316 Bytecodes::Code bc) { | |
317 VM_ENTRY_MARK; | |
318 if (_offset == -1) { | |
319 // at creation we couldn't link to our holder so we need to | |
320 // maintain that stance, otherwise there's no safe way to use this | |
321 // ciField. | |
322 return false; | |
323 } | |
324 | |
325 if (_known_to_link_with == accessing_klass) { | |
326 return true; | |
327 } | |
328 | |
329 FieldAccessInfo result; | |
330 constantPoolHandle c_pool(THREAD, | |
331 accessing_klass->get_instanceKlass()->constants()); | |
332 LinkResolver::resolve_field(result, c_pool, _cp_index, | |
333 Bytecodes::java_code(bc), | |
334 true, false, KILL_COMPILE_ON_FATAL_(false)); | |
335 | |
336 // update the hit-cache, unless there is a problem with memory scoping: | |
337 if (accessing_klass->is_shared() || !is_shared()) | |
338 _known_to_link_with = accessing_klass; | |
339 | |
340 return true; | |
341 } | |
342 | |
343 // ------------------------------------------------------------------ | |
344 // ciField::print | |
345 void ciField::print() { | |
346 tty->print("<ciField "); | |
347 _holder->print_name(); | |
348 tty->print("."); | |
349 _name->print_symbol(); | |
350 tty->print(" offset=%d type=", _offset); | |
351 if (_type != NULL) _type->print_name(); | |
352 else tty->print("(reference)"); | |
353 tty->print(" is_constant=%s", bool_to_str(_is_constant)); | |
1682
e5dfb3ccb88b
6969569: assert(is_static() && is_constant()) failed: illegal call to constant_value()
kvn
parents:
1552
diff
changeset
|
354 if (_is_constant && is_static()) { |
0 | 355 tty->print(" constant_value="); |
356 _constant_value.print(); | |
357 } | |
358 tty->print(">"); | |
359 } | |
360 | |
361 // ------------------------------------------------------------------ | |
362 // ciField::print_name_on | |
363 // | |
364 // Print the name of this field | |
365 void ciField::print_name_on(outputStream* st) { | |
366 name()->print_symbol_on(st); | |
367 } |