Mercurial > hg > truffle
annotate src/share/vm/opto/parse3.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 8033953d67ff |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1252
diff
changeset
|
2 * Copyright (c) 1998, 2010, 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 | |
103 assert(field->will_link(method()->holder(), bc()), "getfield: typeflow responsibility"); | |
104 | |
105 // Note: We do not check for an unloaded field type here any more. | |
106 | |
107 // Generate code for the object pointer. | |
108 Node* obj; | |
109 if (is_field) { | |
110 int obj_depth = is_get ? 0 : field->type()->size(); | |
111 obj = do_null_check(peek(obj_depth), T_OBJECT); | |
112 // Compile-time detect of null-exception? | |
113 if (stopped()) return; | |
114 | |
115 const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder()); | |
116 assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed"); | |
117 | |
118 if (is_get) { | |
119 --_sp; // pop receiver before getting | |
120 do_get_xxx(tjp, obj, field, is_field); | |
121 } else { | |
122 do_put_xxx(tjp, obj, field, is_field); | |
123 --_sp; // pop receiver after putting | |
124 } | |
125 } else { | |
126 const TypeKlassPtr* tkp = TypeKlassPtr::make(field_holder); | |
127 obj = _gvn.makecon(tkp); | |
128 if (is_get) { | |
129 do_get_xxx(tkp, obj, field, is_field); | |
130 } else { | |
131 do_put_xxx(tkp, obj, field, is_field); | |
132 } | |
133 } | |
134 } | |
135 | |
136 | |
137 void Parse::do_get_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) { | |
138 // 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
|
139 if (field->is_constant()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
140 if (field->is_static()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
141 // final static field |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
142 if (push_constant(field->constant_value())) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
143 return; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
144 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
145 else { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
146 // final non-static field of a trusted class ({java,sun}.dyn |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
147 // classes). |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
148 if (obj->is_Con()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
149 const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr(); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
150 ciObject* constant_oop = oop_ptr->const_oop(); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
151 ciConstant constant = field->constant_value_of(constant_oop); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
152 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
153 if (push_constant(constant, true)) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
154 return; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
155 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
156 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
157 } |
0 | 158 |
159 ciType* field_klass = field->type(); | |
160 bool is_vol = field->is_volatile(); | |
161 | |
162 // Compute address and memory type. | |
163 int offset = field->offset_in_bytes(); | |
164 const TypePtr* adr_type = C->alias_type(field)->adr_type(); | |
165 Node *adr = basic_plus_adr(obj, obj, offset); | |
166 BasicType bt = field->layout_type(); | |
167 | |
168 // Build the resultant type of the load | |
169 const Type *type; | |
170 | |
171 bool must_assert_null = false; | |
172 | |
173 if( bt == T_OBJECT ) { | |
174 if (!field->type()->is_loaded()) { | |
175 type = TypeInstPtr::BOTTOM; | |
176 must_assert_null = true; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1100
diff
changeset
|
177 } else if (field->is_constant() && field->is_static()) { |
0 | 178 // This can happen if the constant oop is non-perm. |
179 ciObject* con = field->constant_value().as_object(); | |
180 // Do not "join" in the previous type; it doesn't add value, | |
181 // and may yield a vacuous result if the field is of interface type. | |
182 type = TypeOopPtr::make_from_constant(con)->isa_oopptr(); | |
183 assert(type != NULL, "field singleton type must be consistent"); | |
184 } else { | |
185 type = TypeOopPtr::make_from_klass(field_klass->as_klass()); | |
186 } | |
187 } else { | |
188 type = Type::get_const_basic_type(bt); | |
189 } | |
190 // Build the load. | |
191 Node* ld = make_load(NULL, adr, type, bt, adr_type, is_vol); | |
192 | |
193 // Adjust Java stack | |
194 if (type2size[bt] == 1) | |
195 push(ld); | |
196 else | |
197 push_pair(ld); | |
198 | |
199 if (must_assert_null) { | |
200 // Do not take a trap here. It's possible that the program | |
201 // will never load the field's class, and will happily see | |
202 // null values in this field forever. Don't stumble into a | |
203 // trap for such a program, or we might get a long series | |
204 // of useless recompilations. (Or, we might load a class | |
205 // which should not be loaded.) If we ever see a non-null | |
206 // value, we will then trap and recompile. (The trap will | |
207 // not need to mention the class index, since the class will | |
208 // already have been loaded if we ever see a non-null value.) | |
209 // uncommon_trap(iter().get_field_signature_index()); | |
210 #ifndef PRODUCT | |
211 if (PrintOpto && (Verbose || WizardMode)) { | |
212 method()->print_name(); tty->print_cr(" asserting nullness of field at bci: %d", bci()); | |
213 } | |
214 #endif | |
215 if (C->log() != NULL) { | |
216 C->log()->elem("assert_null reason='field' klass='%d'", | |
217 C->log()->identify(field->type())); | |
218 } | |
219 // If there is going to be a trap, put it at the next bytecode: | |
220 set_bci(iter().next_bci()); | |
221 do_null_assert(peek(), T_OBJECT); | |
222 set_bci(iter().cur_bci()); // put it back | |
223 } | |
224 | |
225 // If reference is volatile, prevent following memory ops from | |
226 // floating up past the volatile read. Also prevents commoning | |
227 // another volatile read. | |
228 if (field->is_volatile()) { | |
229 // Memory barrier includes bogus read of value to force load BEFORE membar | |
230 insert_mem_bar(Op_MemBarAcquire, ld); | |
231 } | |
232 } | |
233 | |
234 void Parse::do_put_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) { | |
235 bool is_vol = field->is_volatile(); | |
236 // If reference is volatile, prevent following memory ops from | |
237 // floating down past the volatile write. Also prevents commoning | |
238 // another volatile read. | |
239 if (is_vol) insert_mem_bar(Op_MemBarRelease); | |
240 | |
241 // Compute address and memory type. | |
242 int offset = field->offset_in_bytes(); | |
243 const TypePtr* adr_type = C->alias_type(field)->adr_type(); | |
244 Node* adr = basic_plus_adr(obj, obj, offset); | |
245 BasicType bt = field->layout_type(); | |
246 // Value to be stored | |
247 Node* val = type2size[bt] == 1 ? pop() : pop_pair(); | |
248 // Round doubles before storing | |
249 if (bt == T_DOUBLE) val = dstore_rounding(val); | |
250 | |
251 // Store the value. | |
252 Node* store; | |
253 if (bt == T_OBJECT) { | |
825 | 254 const TypeOopPtr* field_type; |
0 | 255 if (!field->type()->is_loaded()) { |
256 field_type = TypeInstPtr::BOTTOM; | |
257 } else { | |
258 field_type = TypeOopPtr::make_from_klass(field->type()->as_klass()); | |
259 } | |
260 store = store_oop_to_object( control(), obj, adr, adr_type, val, field_type, bt); | |
261 } else { | |
262 store = store_to_memory( control(), adr, val, bt, adr_type, is_vol ); | |
263 } | |
264 | |
265 // If reference is volatile, prevent following volatiles ops from | |
266 // floating up before the volatile write. | |
267 if (is_vol) { | |
268 // First place the specific membar for THIS volatile index. This first | |
269 // membar is dependent on the store, keeping any other membars generated | |
270 // below from floating up past the store. | |
271 int adr_idx = C->get_alias_index(adr_type); | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
989
diff
changeset
|
272 insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx, store); |
0 | 273 |
274 // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed | |
275 // volatile alias indices. Skip this if the membar is redundant. | |
276 if (adr_idx != Compile::AliasIdxBot) { | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
989
diff
changeset
|
277 insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot, store); |
0 | 278 } |
279 | |
280 // Finally, place alias-index-specific membars for each volatile index | |
281 // that isn't the adr_idx membar. Typically there's only 1 or 2. | |
282 for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) { | |
283 if (i != adr_idx && C->alias_type(i)->is_volatile()) { | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
989
diff
changeset
|
284 insert_mem_bar_volatile(Op_MemBarVolatile, i, store); |
0 | 285 } |
286 } | |
287 } | |
288 | |
289 // If the field is final, the rules of Java say we are in <init> or <clinit>. | |
290 // Note the presence of writes to final non-static fields, so that we | |
291 // can insert a memory barrier later on to keep the writes from floating | |
292 // out of the constructor. | |
293 if (is_field && field->is_final()) { | |
294 set_wrote_final(true); | |
295 } | |
296 } | |
297 | |
298 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
299 bool Parse::push_constant(ciConstant constant, bool require_constant) { |
0 | 300 switch (constant.basic_type()) { |
301 case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break; | |
302 case T_INT: push( intcon(constant.as_int()) ); break; | |
303 case T_CHAR: push( intcon(constant.as_char()) ); break; | |
304 case T_BYTE: push( intcon(constant.as_byte()) ); break; | |
305 case T_SHORT: push( intcon(constant.as_short()) ); break; | |
306 case T_FLOAT: push( makecon(TypeF::make(constant.as_float())) ); break; | |
307 case T_DOUBLE: push_pair( makecon(TypeD::make(constant.as_double())) ); break; | |
308 case T_LONG: push_pair( longcon(constant.as_long()) ); break; | |
309 case T_ARRAY: | |
310 case T_OBJECT: { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
311 // cases: |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
312 // 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
|
313 // 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
|
314 // An oop is not scavengable if it is in the perm gen. |
0 | 315 ciObject* oop_constant = constant.as_object(); |
316 if (oop_constant->is_null_object()) { | |
317 push( zerocon(T_OBJECT) ); | |
318 break; | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
319 } else if (require_constant || oop_constant->should_be_constant()) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
320 push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant)) ); |
0 | 321 break; |
322 } else { | |
323 // we cannot inline the oop, but we can use it later to narrow a type | |
324 return false; | |
325 } | |
326 } | |
327 case T_ILLEGAL: { | |
328 // Invalid ciConstant returned due to OutOfMemoryError in the CI | |
329 assert(C->env()->failing(), "otherwise should not see this"); | |
330 // These always occur because of object types; we are going to | |
331 // bail out anyway, so make the stack depths match up | |
332 push( zerocon(T_OBJECT) ); | |
333 return false; | |
334 } | |
335 default: | |
336 ShouldNotReachHere(); | |
337 return false; | |
338 } | |
339 | |
340 // success | |
341 return true; | |
342 } | |
343 | |
344 | |
345 | |
346 //============================================================================= | |
347 void Parse::do_anewarray() { | |
348 bool will_link; | |
349 ciKlass* klass = iter().get_klass(will_link); | |
350 | |
351 // Uncommon Trap when class that array contains is not loaded | |
352 // we need the loaded class for the rest of graph; do not | |
353 // initialize the container class (see Java spec)!!! | |
354 assert(will_link, "anewarray: typeflow responsibility"); | |
355 | |
356 ciObjArrayKlass* array_klass = ciObjArrayKlass::make(klass); | |
357 // Check that array_klass object is loaded | |
358 if (!array_klass->is_loaded()) { | |
359 // Generate uncommon_trap for unloaded array_class | |
360 uncommon_trap(Deoptimization::Reason_unloaded, | |
361 Deoptimization::Action_reinterpret, | |
362 array_klass); | |
363 return; | |
364 } | |
365 | |
366 kill_dead_locals(); | |
367 | |
368 const TypeKlassPtr* array_klass_type = TypeKlassPtr::make(array_klass); | |
369 Node* count_val = pop(); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
370 Node* obj = new_array(makecon(array_klass_type), count_val, 1); |
0 | 371 push(obj); |
372 } | |
373 | |
374 | |
375 void Parse::do_newarray(BasicType elem_type) { | |
376 kill_dead_locals(); | |
377 | |
378 Node* count_val = pop(); | |
379 const TypeKlassPtr* array_klass = TypeKlassPtr::make(ciTypeArrayKlass::make(elem_type)); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
380 Node* obj = new_array(makecon(array_klass), count_val, 1); |
0 | 381 // Push resultant oop onto stack |
382 push(obj); | |
383 } | |
384 | |
385 // Expand simple expressions like new int[3][5] and new Object[2][nonConLen]. | |
386 // Also handle the degenerate 1-dimensional case of anewarray. | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
387 Node* Parse::expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions, int nargs) { |
0 | 388 Node* length = lengths[0]; |
389 assert(length != NULL, ""); | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
390 Node* array = new_array(makecon(TypeKlassPtr::make(array_klass)), length, nargs); |
0 | 391 if (ndimensions > 1) { |
392 jint length_con = find_int_con(length, -1); | |
393 guarantee(length_con >= 0, "non-constant multianewarray"); | |
394 ciArrayKlass* array_klass_1 = array_klass->as_obj_array_klass()->element_klass()->as_array_klass(); | |
395 const TypePtr* adr_type = TypeAryPtr::OOPS; | |
827
bf3489cc0aa0
6856025: assert(_base >= OopPtr && _base <= KlassPtr,"Not a Java pointer")
never
parents:
825
diff
changeset
|
396 const TypeOopPtr* elemtype = _gvn.type(array)->is_aryptr()->elem()->make_oopptr(); |
0 | 397 const intptr_t header = arrayOopDesc::base_offset_in_bytes(T_OBJECT); |
398 for (jint i = 0; i < length_con; i++) { | |
730
9c6be3edf0dc
6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents:
196
diff
changeset
|
399 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
|
400 intptr_t offset = header + ((intptr_t)i << LogBytesPerHeapOop); |
0 | 401 Node* eaddr = basic_plus_adr(array, offset); |
402 store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT); | |
403 } | |
404 } | |
405 return array; | |
406 } | |
407 | |
408 void Parse::do_multianewarray() { | |
409 int ndimensions = iter().get_dimensions(); | |
410 | |
411 // the m-dimensional array | |
412 bool will_link; | |
413 ciArrayKlass* array_klass = iter().get_klass(will_link)->as_array_klass(); | |
414 assert(will_link, "multianewarray: typeflow responsibility"); | |
415 | |
416 // Note: Array classes are always initialized; no is_initialized check. | |
417 | |
418 enum { MAX_DIMENSION = 5 }; | |
419 if (ndimensions > MAX_DIMENSION || ndimensions <= 0) { | |
420 uncommon_trap(Deoptimization::Reason_unhandled, | |
421 Deoptimization::Action_none); | |
422 return; | |
423 } | |
424 | |
425 kill_dead_locals(); | |
426 | |
427 // get the lengths from the stack (first dimension is on top) | |
428 Node* length[MAX_DIMENSION+1]; | |
429 length[ndimensions] = NULL; // terminating null for make_runtime_call | |
430 int j; | |
431 for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop(); | |
432 | |
433 // The original expression was of this form: new T[length0][length1]... | |
434 // It is often the case that the lengths are small (except the last). | |
435 // If that happens, use the fast 1-d creator a constant number of times. | |
436 const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100); | |
437 jint expand_count = 1; // count of allocations in the expansion | |
438 jint expand_fanout = 1; // running total fanout | |
439 for (j = 0; j < ndimensions-1; j++) { | |
440 jint dim_con = find_int_con(length[j], -1); | |
441 expand_fanout *= dim_con; | |
442 expand_count += expand_fanout; // count the level-J sub-arrays | |
106 | 443 if (dim_con <= 0 |
0 | 444 || dim_con > expand_limit |
445 || expand_count > expand_limit) { | |
446 expand_count = 0; | |
447 break; | |
448 } | |
449 } | |
450 | |
451 // Can use multianewarray instead of [a]newarray if only one dimension, | |
452 // 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
|
453 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
|
454 Node* obj = NULL; |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
455 // 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
|
456 // 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
|
457 // 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
|
458 // 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
|
459 // 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
|
460 { PreserveReexecuteState preexecs(this); |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
461 _sp += ndimensions; |
f516d5d7a019
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents:
1138
diff
changeset
|
462 // 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
|
463 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
|
464 } //original reexecute and sp are set back here |
0 | 465 push(obj); |
466 return; | |
467 } | |
468 | |
469 address fun = NULL; | |
470 switch (ndimensions) { | |
471 //case 1: Actually, there is no case 1. It's handled by new_array. | |
472 case 2: fun = OptoRuntime::multianewarray2_Java(); break; | |
473 case 3: fun = OptoRuntime::multianewarray3_Java(); break; | |
474 case 4: fun = OptoRuntime::multianewarray4_Java(); break; | |
475 case 5: fun = OptoRuntime::multianewarray5_Java(); break; | |
476 default: ShouldNotReachHere(); | |
477 }; | |
478 | |
479 Node* c = make_runtime_call(RC_NO_LEAF | RC_NO_IO, | |
480 OptoRuntime::multianewarray_Type(ndimensions), | |
481 fun, NULL, TypeRawPtr::BOTTOM, | |
482 makecon(TypeKlassPtr::make(array_klass)), | |
483 length[0], length[1], length[2], | |
484 length[3], length[4]); | |
485 Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms)); | |
486 | |
487 const Type* type = TypeOopPtr::make_from_klass_raw(array_klass); | |
488 | |
489 // Improve the type: We know it's not null, exact, and of a given length. | |
490 type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull); | |
491 type = type->is_aryptr()->cast_to_exactness(true); | |
492 | |
493 const TypeInt* ltype = _gvn.find_int_type(length[0]); | |
494 if (ltype != NULL) | |
495 type = type->is_aryptr()->cast_to_size(ltype); | |
496 | |
497 // We cannot sharpen the nested sub-arrays, since the top level is mutable. | |
498 | |
499 Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) ); | |
500 push(cast); | |
501 | |
502 // Possible improvements: | |
503 // - Make a fast path for small multi-arrays. (W/ implicit init. loops.) | |
504 // - Issue CastII against length[*] values, to TypeInt::POS. | |
505 } |