Mercurial > hg > truffle
annotate src/share/vm/opto/parse3.cpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | de95063c0e34 |
children | 45467c53f178 |
rev | line source |
---|---|
0 | 1 /* |
7999
4fcf990aa34a
8006807: C2 crash due to out of bounds array access in Parse::do_multianewarray
drchase
parents:
7428
diff
changeset
|
2 * Copyright (c) 1998, 2013, 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:
1252
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1252
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:
1252
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compileLog.hpp" | |
27 #include "interpreter/linkResolver.hpp" | |
28 #include "memory/universe.inline.hpp" | |
29 #include "oops/objArrayKlass.hpp" | |
30 #include "opto/addnode.hpp" | |
31 #include "opto/memnode.hpp" | |
32 #include "opto/parse.hpp" | |
33 #include "opto/rootnode.hpp" | |
34 #include "opto/runtime.hpp" | |
35 #include "opto/subnode.hpp" | |
36 #include "runtime/deoptimization.hpp" | |
37 #include "runtime/handles.inline.hpp" | |
0 | 38 |
39 //============================================================================= | |
40 // Helper methods for _get* and _put* bytecodes | |
41 //============================================================================= | |
42 bool Parse::static_field_ok_in_clinit(ciField *field, ciMethod *method) { | |
43 // Could be the field_holder's <clinit> method, or <clinit> for a subklass. | |
44 // Better to check now than to Deoptimize as soon as we execute | |
45 assert( field->is_static(), "Only check if field is static"); | |
46 // is_being_initialized() is too generous. It allows access to statics | |
47 // by threads that are not running the <clinit> before the <clinit> finishes. | |
48 // return field->holder()->is_being_initialized(); | |
49 | |
50 // The following restriction is correct but conservative. | |
51 // It is also desirable to allow compilation of methods called from <clinit> | |
52 // but this generated code will need to be made safe for execution by | |
53 // other threads, or the transition from interpreted to compiled code would | |
54 // need to be guarded. | |
55 ciInstanceKlass *field_holder = field->holder(); | |
56 | |
57 bool access_OK = false; | |
58 if (method->holder()->is_subclass_of(field_holder)) { | |
59 if (method->is_static()) { | |
60 if (method->name() == ciSymbol::class_initializer_name()) { | |
61 // OK to access static fields inside initializer | |
62 access_OK = true; | |
63 } | |
64 } else { | |
65 if (method->name() == ciSymbol::object_initializer_name()) { | |
66 // It's also OK to access static fields inside a constructor, | |
67 // because any thread calling the constructor must first have | |
68 // synchronized on the class by executing a '_new' bytecode. | |
69 access_OK = true; | |
70 } | |
71 } | |
72 } | |
73 | |
74 return access_OK; | |
75 | |
76 } | |
77 | |
78 | |
79 void Parse::do_field_access(bool is_get, bool is_field) { | |
80 bool will_link; | |
81 ciField* field = iter().get_field(will_link); | |
82 assert(will_link, "getfield: typeflow responsibility"); | |
83 | |
84 ciInstanceKlass* field_holder = field->holder(); | |
85 | |
86 if (is_field == field->is_static()) { | |
87 // Interpreter will throw java_lang_IncompatibleClassChangeError | |
88 // Check this before allowing <clinit> methods to access static fields | |
89 uncommon_trap(Deoptimization::Reason_unhandled, | |
90 Deoptimization::Action_none); | |
91 return; | |
92 } | |
93 | |
94 if (!is_field && !field_holder->is_initialized()) { | |
95 if (!static_field_ok_in_clinit(field, method())) { | |
96 uncommon_trap(Deoptimization::Reason_uninitialized, | |
97 Deoptimization::Action_reinterpret, | |
98 NULL, "!static_field_ok_in_clinit"); | |
99 return; | |
100 } | |
101 } | |
102 | |
3901
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3852
diff
changeset
|
103 // Deoptimize on putfield writes to call site target field. |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3805
diff
changeset
|
104 if (!is_get && field->is_call_site_target()) { |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3805
diff
changeset
|
105 uncommon_trap(Deoptimization::Reason_unhandled, |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3805
diff
changeset
|
106 Deoptimization::Action_reinterpret, |
3901
aa67216400d3
7085404: JSR 292: VolatileCallSites should have push notification too
twisti
parents:
3852
diff
changeset
|
107 NULL, "put to call site target field"); |
3852
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3805
diff
changeset
|
108 return; |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3805
diff
changeset
|
109 } |
fdb992d83a87
7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents:
3805
diff
changeset
|
110 |
0 | 111 assert(field->will_link(method()->holder(), bc()), "getfield: typeflow responsibility"); |
112 | |
113 // Note: We do not check for an unloaded field type here any more. | |
114 | |
115 // Generate code for the object pointer. | |
116 Node* obj; | |
117 if (is_field) { | |
118 int obj_depth = is_get ? 0 : field->type()->size(); | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6842
diff
changeset
|
119 obj = null_check(peek(obj_depth)); |
0 | 120 // Compile-time detect of null-exception? |
121 if (stopped()) return; | |
122 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
123 #ifdef ASSERT |
0 | 124 const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder()); |
125 assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed"); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
126 #endif |
0 | 127 |
128 if (is_get) { | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6842
diff
changeset
|
129 (void) pop(); // pop receiver before getting |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
130 do_get_xxx(obj, field, is_field); |
0 | 131 } else { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
132 do_put_xxx(obj, field, is_field); |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6842
diff
changeset
|
133 (void) pop(); // pop receiver after putting |
0 | 134 } |
135 } else { | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
136 const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror()); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
137 obj = _gvn.makecon(tip); |
0 | 138 if (is_get) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
139 do_get_xxx(obj, field, is_field); |
0 | 140 } else { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
141 do_put_xxx(obj, field, is_field); |
0 | 142 } |
143 } | |
144 } | |
145 | |
146 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
147 void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { |
0 | 148 // Does this field have a constant value? If so, just push the value. |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
149 if (field->is_constant()) { |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
150 // final or stable field |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
151 const Type* stable_type = NULL; |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
152 if (FoldStableValues && field->is_stable()) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
153 stable_type = Type::get_const_type(field->type()); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
154 if (field->type()->is_array_klass()) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
155 int stable_dimension = field->type()->as_array_klass()->dimension(); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
156 stable_type = stable_type->is_aryptr()->cast_to_stable(true, stable_dimension); |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
157 } |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
158 } |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
159 if (field->is_static()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
160 // final static field |
10278 | 161 if (C->eliminate_boxing()) { |
162 // The pointers in the autobox arrays are always non-null. | |
163 ciSymbol* klass_name = field->holder()->name(); | |
164 if (field->name() == ciSymbol::cache_field_name() && | |
165 field->holder()->uses_default_loader() && | |
166 (klass_name == ciSymbol::java_lang_Character_CharacterCache() || | |
167 klass_name == ciSymbol::java_lang_Byte_ByteCache() || | |
168 klass_name == ciSymbol::java_lang_Short_ShortCache() || | |
169 klass_name == ciSymbol::java_lang_Integer_IntegerCache() || | |
170 klass_name == ciSymbol::java_lang_Long_LongCache())) { | |
171 bool require_const = true; | |
172 bool autobox_cache = true; | |
173 if (push_constant(field->constant_value(), require_const, autobox_cache)) { | |
174 return; | |
175 } | |
176 } | |
177 } | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
178 if (push_constant(field->constant_value(), false, false, stable_type)) |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
179 return; |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
180 } else { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
181 // final or stable non-static field |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3901
diff
changeset
|
182 // Treat final non-static fields of trusted classes (classes in |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3901
diff
changeset
|
183 // java.lang.invoke and sun.invoke packages and subpackages) as |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3901
diff
changeset
|
184 // compile time constants. |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
185 if (obj->is_Con()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
186 const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr(); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
187 ciObject* constant_oop = oop_ptr->const_oop(); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
188 ciConstant constant = field->constant_value_of(constant_oop); |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
189 if (FoldStableValues && field->is_stable() && constant.is_null_or_zero()) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
190 // fall through to field load; the field is not yet initialized |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
191 } else { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
192 if (push_constant(constant, true, false, stable_type)) |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
193 return; |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
194 } |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
195 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
196 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
197 } |
0 | 198 |
199 ciType* field_klass = field->type(); | |
200 bool is_vol = field->is_volatile(); | |
201 | |
202 // Compute address and memory type. | |
203 int offset = field->offset_in_bytes(); | |
204 const TypePtr* adr_type = C->alias_type(field)->adr_type(); | |
205 Node *adr = basic_plus_adr(obj, obj, offset); | |
206 BasicType bt = field->layout_type(); | |
207 | |
208 // Build the resultant type of the load | |
209 const Type *type; | |
210 | |
211 bool must_assert_null = false; | |
212 | |
213 if( bt == T_OBJECT ) { | |
214 if (!field->type()->is_loaded()) { | |
215 type = TypeInstPtr::BOTTOM; | |
216 must_assert_null = true; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
217 } else if (field->is_constant() && field->is_static()) { |
0 | 218 // This can happen if the constant oop is non-perm. |
219 ciObject* con = field->constant_value().as_object(); | |
220 // Do not "join" in the previous type; it doesn't add value, | |
221 // and may yield a vacuous result if the field is of interface type. | |
222 type = TypeOopPtr::make_from_constant(con)->isa_oopptr(); | |
223 assert(type != NULL, "field singleton type must be consistent"); | |
224 } else { | |
225 type = TypeOopPtr::make_from_klass(field_klass->as_klass()); | |
226 } | |
227 } else { | |
228 type = Type::get_const_basic_type(bt); | |
229 } | |
230 // Build the load. | |
231 Node* ld = make_load(NULL, adr, type, bt, adr_type, is_vol); | |
232 | |
233 // Adjust Java stack | |
234 if (type2size[bt] == 1) | |
235 push(ld); | |
236 else | |
237 push_pair(ld); | |
238 | |
239 if (must_assert_null) { | |
240 // Do not take a trap here. It's possible that the program | |
241 // will never load the field's class, and will happily see | |
242 // null values in this field forever. Don't stumble into a | |
243 // trap for such a program, or we might get a long series | |
244 // of useless recompilations. (Or, we might load a class | |
245 // which should not be loaded.) If we ever see a non-null | |
246 // value, we will then trap and recompile. (The trap will | |
247 // not need to mention the class index, since the class will | |
248 // already have been loaded if we ever see a non-null value.) | |
249 // uncommon_trap(iter().get_field_signature_index()); | |
250 #ifndef PRODUCT | |
251 if (PrintOpto && (Verbose || WizardMode)) { | |
252 method()->print_name(); tty->print_cr(" asserting nullness of field at bci: %d", bci()); | |
253 } | |
254 #endif | |
255 if (C->log() != NULL) { | |
256 C->log()->elem("assert_null reason='field' klass='%d'", | |
257 C->log()->identify(field->type())); | |
258 } | |
259 // If there is going to be a trap, put it at the next bytecode: | |
260 set_bci(iter().next_bci()); | |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6842
diff
changeset
|
261 null_assert(peek()); |
0 | 262 set_bci(iter().cur_bci()); // put it back |
263 } | |
264 | |
265 // If reference is volatile, prevent following memory ops from | |
266 // floating up past the volatile read. Also prevents commoning | |
267 // another volatile read. | |
268 if (field->is_volatile()) { | |
269 // Memory barrier includes bogus read of value to force load BEFORE membar | |
270 insert_mem_bar(Op_MemBarAcquire, ld); | |
271 } | |
272 } | |
273 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2357
diff
changeset
|
274 void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { |
0 | 275 bool is_vol = field->is_volatile(); |
276 // If reference is volatile, prevent following memory ops from | |
277 // floating down past the volatile write. Also prevents commoning | |
278 // another volatile read. | |
279 if (is_vol) insert_mem_bar(Op_MemBarRelease); | |
280 | |
281 // Compute address and memory type. | |
282 int offset = field->offset_in_bytes(); | |
283 const TypePtr* adr_type = C->alias_type(field)->adr_type(); | |
284 Node* adr = basic_plus_adr(obj, obj, offset); | |
285 BasicType bt = field->layout_type(); | |
286 // Value to be stored | |
287 Node* val = type2size[bt] == 1 ? pop() : pop_pair(); | |
288 // Round doubles before storing | |
289 if (bt == T_DOUBLE) val = dstore_rounding(val); | |
290 | |
291 // Store the value. | |
292 Node* store; | |
293 if (bt == T_OBJECT) { | |
825 | 294 const TypeOopPtr* field_type; |
0 | 295 if (!field->type()->is_loaded()) { |
296 field_type = TypeInstPtr::BOTTOM; | |
297 } else { | |
298 field_type = TypeOopPtr::make_from_klass(field->type()->as_klass()); | |
299 } | |
300 store = store_oop_to_object( control(), obj, adr, adr_type, val, field_type, bt); | |
301 } else { | |
302 store = store_to_memory( control(), adr, val, bt, adr_type, is_vol ); | |
303 } | |
304 | |
305 // If reference is volatile, prevent following volatiles ops from | |
306 // floating up before the volatile write. | |
307 if (is_vol) { | |
11164
fcf521c3fbc6
8007898: Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier()
kvn
parents:
10278
diff
changeset
|
308 insert_mem_bar(Op_MemBarVolatile); // Use fat membar |
0 | 309 } |
310 | |
311 // If the field is final, the rules of Java say we are in <init> or <clinit>. | |
312 // Note the presence of writes to final non-static fields, so that we | |
313 // can insert a memory barrier later on to keep the writes from floating | |
314 // out of the constructor. | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
315 // Any method can write a @Stable field; insert memory barriers after those also. |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
316 if (is_field && (field->is_final() || field->is_stable())) { |
0 | 317 set_wrote_final(true); |
10278 | 318 // Preserve allocation ptr to create precedent edge to it in membar |
319 // generated on exit from constructor. | |
320 if (C->eliminate_boxing() && | |
321 adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() && | |
322 AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) { | |
323 set_alloc_with_final(obj); | |
324 } | |
0 | 325 } |
326 } | |
327 | |
328 | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
329 |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
330 bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache, const Type* stable_type) { |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
331 const Type* con_type = Type::make_from_constant(constant, require_constant, is_autobox_cache); |
0 | 332 switch (constant.basic_type()) { |
333 case T_ARRAY: | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
334 case T_OBJECT: |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
335 // cases: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
336 // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
337 // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
338 // An oop is not scavengable if it is in the perm gen. |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
339 if (stable_type != NULL && con_type != NULL && con_type->isa_oopptr()) |
17671
de95063c0e34
8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents:
12190
diff
changeset
|
340 con_type = con_type->join_speculative(stable_type); |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
341 break; |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
342 |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
343 case T_ILLEGAL: |
0 | 344 // Invalid ciConstant returned due to OutOfMemoryError in the CI |
345 assert(C->env()->failing(), "otherwise should not see this"); | |
346 // These always occur because of object types; we are going to | |
347 // bail out anyway, so make the stack depths match up | |
348 push( zerocon(T_OBJECT) ); | |
349 return false; | |
350 } | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
351 |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
352 if (con_type == NULL) |
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
353 // we cannot inline the oop, but we can use it later to narrow a type |
0 | 354 return false; |
355 | |
12190
edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents:
11164
diff
changeset
|
356 push_node(constant.basic_type(), makecon(con_type)); |
0 | 357 return true; |
358 } | |
359 | |
360 | |
361 //============================================================================= | |
362 void Parse::do_anewarray() { | |
363 bool will_link; | |
364 ciKlass* klass = iter().get_klass(will_link); | |
365 | |
366 // Uncommon Trap when class that array contains is not loaded | |
367 // we need the loaded class for the rest of graph; do not | |
368 // initialize the container class (see Java spec)!!! | |
369 assert(will_link, "anewarray: typeflow responsibility"); | |
370 | |
371 ciObjArrayKlass* array_klass = ciObjArrayKlass::make(klass); | |
372 // Check that array_klass object is loaded | |
373 if (!array_klass->is_loaded()) { | |
374 // Generate uncommon_trap for unloaded array_class | |
375 uncommon_trap(Deoptimization::Reason_unloaded, | |
376 Deoptimization::Action_reinterpret, | |
377 array_klass); | |
378 return; | |
379 } | |
380 | |
381 kill_dead_locals(); | |
382 | |
383 const TypeKlassPtr* array_klass_type = TypeKlassPtr::make(array_klass); | |
384 Node* count_val = pop(); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
385 Node* obj = new_array(makecon(array_klass_type), count_val, 1); |
0 | 386 push(obj); |
387 } | |
388 | |
389 | |
390 void Parse::do_newarray(BasicType elem_type) { | |
391 kill_dead_locals(); | |
392 | |
393 Node* count_val = pop(); | |
394 const TypeKlassPtr* array_klass = TypeKlassPtr::make(ciTypeArrayKlass::make(elem_type)); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
395 Node* obj = new_array(makecon(array_klass), count_val, 1); |
0 | 396 // Push resultant oop onto stack |
397 push(obj); | |
398 } | |
399 | |
400 // Expand simple expressions like new int[3][5] and new Object[2][nonConLen]. | |
401 // Also handle the degenerate 1-dimensional case of anewarray. | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
402 Node* Parse::expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions, int nargs) { |
0 | 403 Node* length = lengths[0]; |
404 assert(length != NULL, ""); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
405 Node* array = new_array(makecon(TypeKlassPtr::make(array_klass)), length, nargs); |
0 | 406 if (ndimensions > 1) { |
407 jint length_con = find_int_con(length, -1); | |
408 guarantee(length_con >= 0, "non-constant multianewarray"); | |
409 ciArrayKlass* array_klass_1 = array_klass->as_obj_array_klass()->element_klass()->as_array_klass(); | |
410 const TypePtr* adr_type = TypeAryPtr::OOPS; | |
827
bf3489cc0aa0
6856025: assert(_base >= OopPtr && _base <= KlassPtr,"Not a Java pointer")
never
parents:
825
diff
changeset
|
411 const TypeOopPtr* elemtype = _gvn.type(array)->is_aryptr()->elem()->make_oopptr(); |
0 | 412 const intptr_t header = arrayOopDesc::base_offset_in_bytes(T_OBJECT); |
413 for (jint i = 0; i < length_con; i++) { | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
414 Node* elem = expand_multianewarray(array_klass_1, &lengths[1], ndimensions-1, nargs); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
106
diff
changeset
|
415 intptr_t offset = header + ((intptr_t)i << LogBytesPerHeapOop); |
0 | 416 Node* eaddr = basic_plus_adr(array, offset); |
417 store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT); | |
418 } | |
419 } | |
420 return array; | |
421 } | |
422 | |
423 void Parse::do_multianewarray() { | |
424 int ndimensions = iter().get_dimensions(); | |
425 | |
426 // the m-dimensional array | |
427 bool will_link; | |
428 ciArrayKlass* array_klass = iter().get_klass(will_link)->as_array_klass(); | |
429 assert(will_link, "multianewarray: typeflow responsibility"); | |
430 | |
431 // Note: Array classes are always initialized; no is_initialized check. | |
432 | |
433 kill_dead_locals(); | |
434 | |
435 // get the lengths from the stack (first dimension is on top) | |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
436 Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1); |
0 | 437 length[ndimensions] = NULL; // terminating null for make_runtime_call |
438 int j; | |
439 for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop(); | |
440 | |
441 // The original expression was of this form: new T[length0][length1]... | |
442 // It is often the case that the lengths are small (except the last). | |
443 // If that happens, use the fast 1-d creator a constant number of times. | |
444 const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100); | |
445 jint expand_count = 1; // count of allocations in the expansion | |
446 jint expand_fanout = 1; // running total fanout | |
447 for (j = 0; j < ndimensions-1; j++) { | |
448 jint dim_con = find_int_con(length[j], -1); | |
449 expand_fanout *= dim_con; | |
450 expand_count += expand_fanout; // count the level-J sub-arrays | |
106 | 451 if (dim_con <= 0 |
0 | 452 || dim_con > expand_limit |
453 || expand_count > expand_limit) { | |
454 expand_count = 0; | |
455 break; | |
456 } | |
457 } | |
458 | |
459 // Can use multianewarray instead of [a]newarray if only one dimension, | |
460 // or if all non-final dimensions are small constants. | |
1252
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
461 if (ndimensions == 1 || (1 <= expand_count && expand_count <= expand_limit)) { |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
462 Node* obj = NULL; |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
463 // Set the original stack and the reexecute bit for the interpreter |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
464 // to reexecute the multianewarray bytecode if deoptimization happens. |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
465 // Do it unconditionally even for one dimension multianewarray. |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
466 // Note: the reexecute bit will be set in GraphKit::add_safepoint_edges() |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
467 // when AllocateArray node for newarray is created. |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
468 { PreserveReexecuteState preexecs(this); |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6842
diff
changeset
|
469 inc_sp(ndimensions); |
1252
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
470 // Pass 0 as nargs since uncommon trap code does not need to restore stack. |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
471 obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0); |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
472 } //original reexecute and sp are set back here |
0 | 473 push(obj); |
474 return; | |
475 } | |
476 | |
477 address fun = NULL; | |
478 switch (ndimensions) { | |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
479 case 1: ShouldNotReachHere(); break; |
0 | 480 case 2: fun = OptoRuntime::multianewarray2_Java(); break; |
481 case 3: fun = OptoRuntime::multianewarray3_Java(); break; | |
482 case 4: fun = OptoRuntime::multianewarray4_Java(); break; | |
483 case 5: fun = OptoRuntime::multianewarray5_Java(); break; | |
484 }; | |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
485 Node* c = NULL; |
0 | 486 |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
487 if (fun != NULL) { |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
488 c = make_runtime_call(RC_NO_LEAF | RC_NO_IO, |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
489 OptoRuntime::multianewarray_Type(ndimensions), |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
490 fun, NULL, TypeRawPtr::BOTTOM, |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
491 makecon(TypeKlassPtr::make(array_klass)), |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
492 length[0], length[1], length[2], |
7999
4fcf990aa34a
8006807: C2 crash due to out of bounds array access in Parse::do_multianewarray
drchase
parents:
7428
diff
changeset
|
493 (ndimensions > 2) ? length[3] : NULL, |
4fcf990aa34a
8006807: C2 crash due to out of bounds array access in Parse::do_multianewarray
drchase
parents:
7428
diff
changeset
|
494 (ndimensions > 3) ? length[4] : NULL); |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
495 } else { |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
496 // Create a java array for dimension sizes |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
497 Node* dims = NULL; |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
498 { PreserveReexecuteState preexecs(this); |
7194
beebba0acc11
7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents:
6842
diff
changeset
|
499 inc_sp(ndimensions); |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
500 Node* dims_array_klass = makecon(TypeKlassPtr::make(ciArrayKlass::make(ciType::make(T_INT)))); |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
501 dims = new_array(dims_array_klass, intcon(ndimensions), 0); |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
502 |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
503 // Fill-in it with values |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
504 for (j = 0; j < ndimensions; j++) { |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
505 Node *dims_elem = array_element_address(dims, intcon(j), T_INT); |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
506 store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS); |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
507 } |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
508 } |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
509 |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
510 c = make_runtime_call(RC_NO_LEAF | RC_NO_IO, |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
511 OptoRuntime::multianewarrayN_Type(), |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
512 OptoRuntime::multianewarrayN_Java(), NULL, TypeRawPtr::BOTTOM, |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
513 makecon(TypeKlassPtr::make(array_klass)), |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
514 dims); |
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
515 } |
7428
2d6c433b1f38
8004741: Missing compiled exception handle table entry for multidimensional array allocation
kvn
parents:
7194
diff
changeset
|
516 make_slow_call_ex(c, env()->Throwable_klass(), false); |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
517 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
3902
diff
changeset
|
518 Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms)); |
0 | 519 |
520 const Type* type = TypeOopPtr::make_from_klass_raw(array_klass); | |
521 | |
522 // Improve the type: We know it's not null, exact, and of a given length. | |
523 type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull); | |
524 type = type->is_aryptr()->cast_to_exactness(true); | |
525 | |
526 const TypeInt* ltype = _gvn.find_int_type(length[0]); | |
527 if (ltype != NULL) | |
528 type = type->is_aryptr()->cast_to_size(ltype); | |
529 | |
3805
263247c478c5
7058510: multinewarray with 6 dimensions uncommon traps in server compiler
iveresov
parents:
2376
diff
changeset
|
530 // We cannot sharpen the nested sub-arrays, since the top level is mutable. |
0 | 531 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
3902
diff
changeset
|
532 Node* cast = _gvn.transform( new (C) CheckCastPPNode(control(), res, type) ); |
0 | 533 push(cast); |
534 | |
535 // Possible improvements: | |
536 // - Make a fast path for small multi-arrays. (W/ implicit init. loops.) | |
537 // - Issue CastII against length[*] values, to TypeInt::POS. | |
538 } |