annotate src/share/vm/opto/parse3.cpp @ 1145:e018e6884bd8

6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
author ysr
date Wed, 23 Dec 2009 09:23:54 -0800
parents 148e5441d916
children f96a1a986f7b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
844
bd02caa94611 6862919: Update copyright year
xdono
parents: 827
diff changeset
2 * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_parse3.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Helper methods for _get* and _put* bytecodes
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
31 bool Parse::static_field_ok_in_clinit(ciField *field, ciMethod *method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Could be the field_holder's <clinit> method, or <clinit> for a subklass.
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // Better to check now than to Deoptimize as soon as we execute
a61af66fc99e Initial load
duke
parents:
diff changeset
34 assert( field->is_static(), "Only check if field is static");
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // is_being_initialized() is too generous. It allows access to statics
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // by threads that are not running the <clinit> before the <clinit> finishes.
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // return field->holder()->is_being_initialized();
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // The following restriction is correct but conservative.
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // It is also desirable to allow compilation of methods called from <clinit>
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // but this generated code will need to be made safe for execution by
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // other threads, or the transition from interpreted to compiled code would
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // need to be guarded.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 ciInstanceKlass *field_holder = field->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 bool access_OK = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 if (method->holder()->is_subclass_of(field_holder)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 if (method->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 if (method->name() == ciSymbol::class_initializer_name()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // OK to access static fields inside initializer
a61af66fc99e Initial load
duke
parents:
diff changeset
51 access_OK = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 }
a61af66fc99e Initial load
duke
parents:
diff changeset
53 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 if (method->name() == ciSymbol::object_initializer_name()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // It's also OK to access static fields inside a constructor,
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // because any thread calling the constructor must first have
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // synchronized on the class by executing a '_new' bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
58 access_OK = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 return access_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 void Parse::do_field_access(bool is_get, bool is_field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 ciField* field = iter().get_field(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 assert(will_link, "getfield: typeflow responsibility");
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 ciInstanceKlass* field_holder = field->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if (is_field == field->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Interpreter will throw java_lang_IncompatibleClassChangeError
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // Check this before allowing <clinit> methods to access static fields
a61af66fc99e Initial load
duke
parents:
diff changeset
78 uncommon_trap(Deoptimization::Reason_unhandled,
a61af66fc99e Initial load
duke
parents:
diff changeset
79 Deoptimization::Action_none);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if (!is_field && !field_holder->is_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (!static_field_ok_in_clinit(field, method())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 uncommon_trap(Deoptimization::Reason_uninitialized,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 Deoptimization::Action_reinterpret,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 NULL, "!static_field_ok_in_clinit");
a61af66fc99e Initial load
duke
parents:
diff changeset
88 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 assert(field->will_link(method()->holder(), bc()), "getfield: typeflow responsibility");
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // Note: We do not check for an unloaded field type here any more.
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Generate code for the object pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
97 Node* obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (is_field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 int obj_depth = is_get ? 0 : field->type()->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
100 obj = do_null_check(peek(obj_depth), T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Compile-time detect of null-exception?
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (stopped()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
105 assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed");
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 if (is_get) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 --_sp; // pop receiver before getting
a61af66fc99e Initial load
duke
parents:
diff changeset
109 do_get_xxx(tjp, obj, field, is_field);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 do_put_xxx(tjp, obj, field, is_field);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 --_sp; // pop receiver after putting
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 const TypeKlassPtr* tkp = TypeKlassPtr::make(field_holder);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 obj = _gvn.makecon(tkp);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if (is_get) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 do_get_xxx(tkp, obj, field, is_field);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 do_put_xxx(tkp, obj, field, is_field);
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 void Parse::do_get_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Does this field have a constant value? If so, just push the value.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 if (field->is_constant() && push_constant(field->constant_value())) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 ciType* field_klass = field->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
131 bool is_vol = field->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // Compute address and memory type.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 int offset = field->offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 const TypePtr* adr_type = C->alias_type(field)->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 Node *adr = basic_plus_adr(obj, obj, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 BasicType bt = field->layout_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Build the resultant type of the load
a61af66fc99e Initial load
duke
parents:
diff changeset
140 const Type *type;
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 bool must_assert_null = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 if( bt == T_OBJECT ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 if (!field->type()->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 type = TypeInstPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 must_assert_null = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 } else if (field->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // This can happen if the constant oop is non-perm.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 ciObject* con = field->constant_value().as_object();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Do not "join" in the previous type; it doesn't add value,
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // and may yield a vacuous result if the field is of interface type.
a61af66fc99e Initial load
duke
parents:
diff changeset
153 type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 assert(type != NULL, "field singleton type must be consistent");
a61af66fc99e Initial load
duke
parents:
diff changeset
155 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 type = TypeOopPtr::make_from_klass(field_klass->as_klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 type = Type::get_const_basic_type(bt);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Build the load.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 Node* ld = make_load(NULL, adr, type, bt, adr_type, is_vol);
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Adjust Java stack
a61af66fc99e Initial load
duke
parents:
diff changeset
165 if (type2size[bt] == 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
166 push(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 else
a61af66fc99e Initial load
duke
parents:
diff changeset
168 push_pair(ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (must_assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Do not take a trap here. It's possible that the program
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // will never load the field's class, and will happily see
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // null values in this field forever. Don't stumble into a
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // trap for such a program, or we might get a long series
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // of useless recompilations. (Or, we might load a class
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // which should not be loaded.) If we ever see a non-null
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // value, we will then trap and recompile. (The trap will
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // not need to mention the class index, since the class will
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // already have been loaded if we ever see a non-null value.)
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // uncommon_trap(iter().get_field_signature_index());
a61af66fc99e Initial load
duke
parents:
diff changeset
181 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if (PrintOpto && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 method()->print_name(); tty->print_cr(" asserting nullness of field at bci: %d", bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 C->log()->elem("assert_null reason='field' klass='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
188 C->log()->identify(field->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // If there is going to be a trap, put it at the next bytecode:
a61af66fc99e Initial load
duke
parents:
diff changeset
191 set_bci(iter().next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
192 do_null_assert(peek(), T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 set_bci(iter().cur_bci()); // put it back
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // If reference is volatile, prevent following memory ops from
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // floating up past the volatile read. Also prevents commoning
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // another volatile read.
a61af66fc99e Initial load
duke
parents:
diff changeset
199 if (field->is_volatile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Memory barrier includes bogus read of value to force load BEFORE membar
a61af66fc99e Initial load
duke
parents:
diff changeset
201 insert_mem_bar(Op_MemBarAcquire, ld);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 void Parse::do_put_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 bool is_vol = field->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // If reference is volatile, prevent following memory ops from
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // floating down past the volatile write. Also prevents commoning
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // another volatile read.
a61af66fc99e Initial load
duke
parents:
diff changeset
210 if (is_vol) insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // Compute address and memory type.
a61af66fc99e Initial load
duke
parents:
diff changeset
213 int offset = field->offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
214 const TypePtr* adr_type = C->alias_type(field)->adr_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
215 Node* adr = basic_plus_adr(obj, obj, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 BasicType bt = field->layout_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Value to be stored
a61af66fc99e Initial load
duke
parents:
diff changeset
218 Node* val = type2size[bt] == 1 ? pop() : pop_pair();
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Round doubles before storing
a61af66fc99e Initial load
duke
parents:
diff changeset
220 if (bt == T_DOUBLE) val = dstore_rounding(val);
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // Store the value.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 Node* store;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if (bt == T_OBJECT) {
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 730
diff changeset
225 const TypeOopPtr* field_type;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
226 if (!field->type()->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 field_type = TypeInstPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 field_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 store = store_oop_to_object( control(), obj, adr, adr_type, val, field_type, bt);
a61af66fc99e Initial load
duke
parents:
diff changeset
232 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 store = store_to_memory( control(), adr, val, bt, adr_type, is_vol );
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // If reference is volatile, prevent following volatiles ops from
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // floating up before the volatile write.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 if (is_vol) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // First place the specific membar for THIS volatile index. This first
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // membar is dependent on the store, keeping any other membars generated
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // below from floating up past the store.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 int adr_idx = C->get_alias_index(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 insert_mem_bar_volatile(Op_MemBarVolatile, adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Now place a membar for AliasIdxBot for the unknown yet-to-be-parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // volatile alias indices. Skip this if the membar is redundant.
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (adr_idx != Compile::AliasIdxBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 insert_mem_bar_volatile(Op_MemBarVolatile, Compile::AliasIdxBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Finally, place alias-index-specific membars for each volatile index
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // that isn't the adr_idx membar. Typically there's only 1 or 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 for( int i = Compile::AliasIdxRaw; i < C->num_alias_types(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if (i != adr_idx && C->alias_type(i)->is_volatile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 insert_mem_bar_volatile(Op_MemBarVolatile, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // If the field is final, the rules of Java say we are in <init> or <clinit>.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // Note the presence of writes to final non-static fields, so that we
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // can insert a memory barrier later on to keep the writes from floating
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // out of the constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 if (is_field && field->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 set_wrote_final(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
270 bool Parse::push_constant(ciConstant constant, bool require_constant) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
271 switch (constant.basic_type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 case T_INT: push( intcon(constant.as_int()) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 case T_CHAR: push( intcon(constant.as_char()) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 case T_BYTE: push( intcon(constant.as_byte()) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 case T_SHORT: push( intcon(constant.as_short()) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 case T_FLOAT: push( makecon(TypeF::make(constant.as_float())) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 case T_DOUBLE: push_pair( makecon(TypeD::make(constant.as_double())) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
279 case T_LONG: push_pair( longcon(constant.as_long()) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
280 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
281 case T_OBJECT: {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
282 // cases:
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
283 // 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
284 // 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
285 // An oop is not scavengable if it is in the perm gen.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
286 ciObject* oop_constant = constant.as_object();
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (oop_constant->is_null_object()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 push( zerocon(T_OBJECT) );
a61af66fc99e Initial load
duke
parents:
diff changeset
289 break;
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
290 } 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
291 push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
292 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // we cannot inline the oop, but we can use it later to narrow a type
a61af66fc99e Initial load
duke
parents:
diff changeset
295 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298 case T_ILLEGAL: {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // Invalid ciConstant returned due to OutOfMemoryError in the CI
a61af66fc99e Initial load
duke
parents:
diff changeset
300 assert(C->env()->failing(), "otherwise should not see this");
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // These always occur because of object types; we are going to
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // bail out anyway, so make the stack depths match up
a61af66fc99e Initial load
duke
parents:
diff changeset
303 push( zerocon(T_OBJECT) );
a61af66fc99e Initial load
duke
parents:
diff changeset
304 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
306 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
307 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
308 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // success
a61af66fc99e Initial load
duke
parents:
diff changeset
312 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
318 void Parse::do_anewarray() {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 ciKlass* klass = iter().get_klass(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // Uncommon Trap when class that array contains is not loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // we need the loaded class for the rest of graph; do not
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // initialize the container class (see Java spec)!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
325 assert(will_link, "anewarray: typeflow responsibility");
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 ciObjArrayKlass* array_klass = ciObjArrayKlass::make(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Check that array_klass object is loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
329 if (!array_klass->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Generate uncommon_trap for unloaded array_class
a61af66fc99e Initial load
duke
parents:
diff changeset
331 uncommon_trap(Deoptimization::Reason_unloaded,
a61af66fc99e Initial load
duke
parents:
diff changeset
332 Deoptimization::Action_reinterpret,
a61af66fc99e Initial load
duke
parents:
diff changeset
333 array_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 const TypeKlassPtr* array_klass_type = TypeKlassPtr::make(array_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 Node* count_val = pop();
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 196
diff changeset
341 Node* obj = new_array(makecon(array_klass_type), count_val, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
342 push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 void Parse::do_newarray(BasicType elem_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 Node* count_val = pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 const TypeKlassPtr* array_klass = TypeKlassPtr::make(ciTypeArrayKlass::make(elem_type));
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 196
diff changeset
351 Node* obj = new_array(makecon(array_klass), count_val, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Push resultant oop onto stack
a61af66fc99e Initial load
duke
parents:
diff changeset
353 push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // Expand simple expressions like new int[3][5] and new Object[2][nonConLen].
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // Also handle the degenerate 1-dimensional case of anewarray.
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 196
diff changeset
358 Node* Parse::expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions, int nargs) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
359 Node* length = lengths[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
360 assert(length != NULL, "");
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 196
diff changeset
361 Node* array = new_array(makecon(TypeKlassPtr::make(array_klass)), length, nargs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if (ndimensions > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 jint length_con = find_int_con(length, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 guarantee(length_con >= 0, "non-constant multianewarray");
a61af66fc99e Initial load
duke
parents:
diff changeset
365 ciArrayKlass* array_klass_1 = array_klass->as_obj_array_klass()->element_klass()->as_array_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
366 const TypePtr* adr_type = TypeAryPtr::OOPS;
827
bf3489cc0aa0 6856025: assert(_base >= OopPtr && _base <= KlassPtr,"Not a Java pointer")
never
parents: 825
diff changeset
367 const TypeOopPtr* elemtype = _gvn.type(array)->is_aryptr()->elem()->make_oopptr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
368 const intptr_t header = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
369 for (jint i = 0; i < length_con; i++) {
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 196
diff changeset
370 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
371 intptr_t offset = header + ((intptr_t)i << LogBytesPerHeapOop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
372 Node* eaddr = basic_plus_adr(array, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 return array;
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 void Parse::do_multianewarray() {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 int ndimensions = iter().get_dimensions();
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // the m-dimensional array
a61af66fc99e Initial load
duke
parents:
diff changeset
383 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 ciArrayKlass* array_klass = iter().get_klass(will_link)->as_array_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
385 assert(will_link, "multianewarray: typeflow responsibility");
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Note: Array classes are always initialized; no is_initialized check.
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 enum { MAX_DIMENSION = 5 };
a61af66fc99e Initial load
duke
parents:
diff changeset
390 if (ndimensions > MAX_DIMENSION || ndimensions <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 uncommon_trap(Deoptimization::Reason_unhandled,
a61af66fc99e Initial load
duke
parents:
diff changeset
392 Deoptimization::Action_none);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // get the lengths from the stack (first dimension is on top)
a61af66fc99e Initial load
duke
parents:
diff changeset
399 Node* length[MAX_DIMENSION+1];
a61af66fc99e Initial load
duke
parents:
diff changeset
400 length[ndimensions] = NULL; // terminating null for make_runtime_call
a61af66fc99e Initial load
duke
parents:
diff changeset
401 int j;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // The original expression was of this form: new T[length0][length1]...
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // It is often the case that the lengths are small (except the last).
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // If that happens, use the fast 1-d creator a constant number of times.
a61af66fc99e Initial load
duke
parents:
diff changeset
407 const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 jint expand_count = 1; // count of allocations in the expansion
a61af66fc99e Initial load
duke
parents:
diff changeset
409 jint expand_fanout = 1; // running total fanout
a61af66fc99e Initial load
duke
parents:
diff changeset
410 for (j = 0; j < ndimensions-1; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 jint dim_con = find_int_con(length[j], -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 expand_fanout *= dim_con;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 expand_count += expand_fanout; // count the level-J sub-arrays
106
c9314fa4f757 6663908: NegativeArraySizeException is not thrown
rasbold
parents: 0
diff changeset
414 if (dim_con <= 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
415 || dim_con > expand_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
416 || expand_count > expand_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 expand_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // Can use multianewarray instead of [a]newarray if only one dimension,
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // or if all non-final dimensions are small constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 196
diff changeset
425 Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions, ndimensions);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
426 push(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 address fun = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
431 switch (ndimensions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
432 //case 1: Actually, there is no case 1. It's handled by new_array.
a61af66fc99e Initial load
duke
parents:
diff changeset
433 case 2: fun = OptoRuntime::multianewarray2_Java(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
434 case 3: fun = OptoRuntime::multianewarray3_Java(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
435 case 4: fun = OptoRuntime::multianewarray4_Java(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
436 case 5: fun = OptoRuntime::multianewarray5_Java(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
437 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 };
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 Node* c = make_runtime_call(RC_NO_LEAF | RC_NO_IO,
a61af66fc99e Initial load
duke
parents:
diff changeset
441 OptoRuntime::multianewarray_Type(ndimensions),
a61af66fc99e Initial load
duke
parents:
diff changeset
442 fun, NULL, TypeRawPtr::BOTTOM,
a61af66fc99e Initial load
duke
parents:
diff changeset
443 makecon(TypeKlassPtr::make(array_klass)),
a61af66fc99e Initial load
duke
parents:
diff changeset
444 length[0], length[1], length[2],
a61af66fc99e Initial load
duke
parents:
diff changeset
445 length[3], length[4]);
a61af66fc99e Initial load
duke
parents:
diff changeset
446 Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Improve the type: We know it's not null, exact, and of a given length.
a61af66fc99e Initial load
duke
parents:
diff changeset
451 type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 type = type->is_aryptr()->cast_to_exactness(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 const TypeInt* ltype = _gvn.find_int_type(length[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 if (ltype != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
456 type = type->is_aryptr()->cast_to_size(ltype);
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // We cannot sharpen the nested sub-arrays, since the top level is mutable.
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
a61af66fc99e Initial load
duke
parents:
diff changeset
461 push(cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // Possible improvements:
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // - Make a fast path for small multi-arrays. (W/ implicit init. loops.)
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // - Issue CastII against length[*] values, to TypeInt::POS.
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }