annotate src/share/vm/opto/parse3.cpp @ 1721:413ad0331a0c

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