File: | jdk/src/hotspot/share/opto/parseHelper.cpp |
Warning: | line 144, column 9 Value stored to 'idx' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "ci/ciSymbols.hpp" |
27 | #include "compiler/compileLog.hpp" |
28 | #include "oops/objArrayKlass.hpp" |
29 | #include "opto/addnode.hpp" |
30 | #include "opto/memnode.hpp" |
31 | #include "opto/mulnode.hpp" |
32 | #include "opto/parse.hpp" |
33 | #include "opto/rootnode.hpp" |
34 | #include "opto/runtime.hpp" |
35 | #include "runtime/sharedRuntime.hpp" |
36 | |
37 | //------------------------------make_dtrace_method_entry_exit ---------------- |
38 | // Dtrace -- record entry or exit of a method if compiled with dtrace support |
39 | void GraphKit::make_dtrace_method_entry_exit(ciMethod* method, bool is_entry) { |
40 | const TypeFunc *call_type = OptoRuntime::dtrace_method_entry_exit_Type(); |
41 | address call_address = is_entry ? CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry)((address)((address_word)(SharedRuntime::dtrace_method_entry) )) : |
42 | CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)((address)((address_word)(SharedRuntime::dtrace_method_exit)) ); |
43 | const char *call_name = is_entry ? "dtrace_method_entry" : "dtrace_method_exit"; |
44 | |
45 | // Get base of thread-local storage area |
46 | Node* thread = _gvn.transform( new ThreadLocalNode() ); |
47 | |
48 | // Get method |
49 | const TypePtr* method_type = TypeMetadataPtr::make(method); |
50 | Node *method_node = _gvn.transform(ConNode::make(method_type)); |
51 | |
52 | kill_dead_locals(); |
53 | |
54 | // For some reason, this call reads only raw memory. |
55 | const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; |
56 | make_runtime_call(RC_LEAF | RC_NARROW_MEM, |
57 | call_type, call_address, |
58 | call_name, raw_adr_type, |
59 | thread, method_node); |
60 | } |
61 | |
62 | |
63 | //============================================================================= |
64 | //------------------------------do_checkcast----------------------------------- |
65 | void Parse::do_checkcast() { |
66 | bool will_link; |
67 | ciKlass* klass = iter().get_klass(will_link); |
68 | |
69 | Node *obj = peek(); |
70 | |
71 | // Throw uncommon trap if class is not loaded or the value we are casting |
72 | // _from_ is not loaded, and value is not null. If the value _is_ NULL, |
73 | // then the checkcast does nothing. |
74 | const TypeOopPtr *tp = _gvn.type(obj)->isa_oopptr(); |
75 | if (!will_link || (tp && tp->klass() && !tp->klass()->is_loaded())) { |
76 | if (C->log() != NULL__null) { |
77 | if (!will_link) { |
78 | C->log()->elem("assert_null reason='checkcast' klass='%d'", |
79 | C->log()->identify(klass)); |
80 | } |
81 | if (tp && tp->klass() && !tp->klass()->is_loaded()) { |
82 | // %%% Cannot happen? |
83 | C->log()->elem("assert_null reason='checkcast source' klass='%d'", |
84 | C->log()->identify(tp->klass())); |
85 | } |
86 | } |
87 | null_assert(obj); |
88 | assert( stopped() || _gvn.type(peek())->higher_equal(TypePtr::NULL_PTR), "what's left behind is null" )do { if (!(stopped() || _gvn.type(peek())->higher_equal(TypePtr ::NULL_PTR))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/parseHelper.cpp" , 88, "assert(" "stopped() || _gvn.type(peek())->higher_equal(TypePtr::NULL_PTR)" ") failed", "what's left behind is null"); ::breakpoint(); } } while (0); |
89 | return; |
90 | } |
91 | |
92 | Node* res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass))); |
93 | if (stopped()) { |
94 | return; |
95 | } |
96 | |
97 | // Pop from stack AFTER gen_checkcast because it can uncommon trap and |
98 | // the debug info has to be correct. |
99 | pop(); |
100 | push(res); |
101 | } |
102 | |
103 | |
104 | //------------------------------do_instanceof---------------------------------- |
105 | void Parse::do_instanceof() { |
106 | if (stopped()) return; |
107 | // We would like to return false if class is not loaded, emitting a |
108 | // dependency, but Java requires instanceof to load its operand. |
109 | |
110 | // Throw uncommon trap if class is not loaded |
111 | bool will_link; |
112 | ciKlass* klass = iter().get_klass(will_link); |
113 | |
114 | if (!will_link) { |
115 | if (C->log() != NULL__null) { |
116 | C->log()->elem("assert_null reason='instanceof' klass='%d'", |
117 | C->log()->identify(klass)); |
118 | } |
119 | null_assert(peek()); |
120 | assert( stopped() || _gvn.type(peek())->higher_equal(TypePtr::NULL_PTR), "what's left behind is null" )do { if (!(stopped() || _gvn.type(peek())->higher_equal(TypePtr ::NULL_PTR))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/parseHelper.cpp" , 120, "assert(" "stopped() || _gvn.type(peek())->higher_equal(TypePtr::NULL_PTR)" ") failed", "what's left behind is null"); ::breakpoint(); } } while (0); |
121 | if (!stopped()) { |
122 | // The object is now known to be null. |
123 | // Shortcut the effect of gen_instanceof and return "false" directly. |
124 | pop(); // pop the null |
125 | push(_gvn.intcon(0)); // push false answer |
126 | } |
127 | return; |
128 | } |
129 | |
130 | // Push the bool result back on stack |
131 | Node* res = gen_instanceof(peek(), makecon(TypeKlassPtr::make(klass)), true); |
132 | |
133 | // Pop from stack AFTER gen_instanceof because it can uncommon trap. |
134 | pop(); |
135 | push(res); |
136 | } |
137 | |
138 | //------------------------------array_store_check------------------------------ |
139 | // pull array from stack and check that the store is valid |
140 | void Parse::array_store_check() { |
141 | |
142 | // Shorthand access to array store elements without popping them. |
143 | Node *obj = peek(0); |
144 | Node *idx = peek(1); |
Value stored to 'idx' during its initialization is never read | |
145 | Node *ary = peek(2); |
146 | |
147 | if (_gvn.type(obj) == TypePtr::NULL_PTR) { |
148 | // There's never a type check on null values. |
149 | // This cutout lets us avoid the uncommon_trap(Reason_array_check) |
150 | // below, which turns into a performance liability if the |
151 | // gen_checkcast folds up completely. |
152 | return; |
153 | } |
154 | |
155 | // Extract the array klass type |
156 | int klass_offset = oopDesc::klass_offset_in_bytes(); |
157 | Node* p = basic_plus_adr( ary, ary, klass_offset ); |
158 | // p's type is array-of-OOPS plus klass_offset |
159 | Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL__null, immutable_memory(), p, TypeInstPtr::KLASS)); |
160 | // Get the array klass |
161 | const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr(); |
162 | |
163 | // The type of array_klass is usually INexact array-of-oop. Heroically |
164 | // cast array_klass to EXACT array and uncommon-trap if the cast fails. |
165 | // Make constant out of the inexact array klass, but use it only if the cast |
166 | // succeeds. |
167 | bool always_see_exact_class = false; |
168 | if (MonomorphicArrayCheck |
169 | && !too_many_traps(Deoptimization::Reason_array_check) |
170 | && !tak->klass_is_exact() |
171 | && tak != TypeInstKlassPtr::OBJECT) { |
172 | // Regarding the fourth condition in the if-statement from above: |
173 | // |
174 | // If the compiler has determined that the type of array 'ary' (represented |
175 | // by 'array_klass') is java/lang/Object, the compiler must not assume that |
176 | // the array 'ary' is monomorphic. |
177 | // |
178 | // If 'ary' were of type java/lang/Object, this arraystore would have to fail, |
179 | // because it is not possible to perform a arraystore into an object that is not |
180 | // a "proper" array. |
181 | // |
182 | // Therefore, let's obtain at runtime the type of 'ary' and check if we can still |
183 | // successfully perform the store. |
184 | // |
185 | // The implementation reasons for the condition are the following: |
186 | // |
187 | // java/lang/Object is the superclass of all arrays, but it is represented by the VM |
188 | // as an InstanceKlass. The checks generated by gen_checkcast() (see below) expect |
189 | // 'array_klass' to be ObjArrayKlass, which can result in invalid memory accesses. |
190 | // |
191 | // See issue JDK-8057622 for details. |
192 | |
193 | always_see_exact_class = true; |
194 | // (If no MDO at all, hope for the best, until a trap actually occurs.) |
195 | |
196 | // Make a constant out of the inexact array klass |
197 | const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr(); |
198 | Node* con = makecon(extak); |
199 | Node* cmp = _gvn.transform(new CmpPNode( array_klass, con )); |
200 | Node* bol = _gvn.transform(new BoolNode( cmp, BoolTest::eq )); |
201 | Node* ctrl= control(); |
202 | { BuildCutout unless(this, bol, PROB_MAX(1.0f-(1e-6f))); |
203 | uncommon_trap(Deoptimization::Reason_array_check, |
204 | Deoptimization::Action_maybe_recompile, |
205 | tak->klass()); |
206 | } |
207 | if (stopped()) { // MUST uncommon-trap? |
208 | set_control(ctrl); // Then Don't Do It, just fall into the normal checking |
209 | } else { // Cast array klass to exactness: |
210 | // Use the exact constant value we know it is. |
211 | replace_in_map(array_klass,con); |
212 | CompileLog* log = C->log(); |
213 | if (log != NULL__null) { |
214 | log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'", |
215 | log->identify(tak->klass())); |
216 | } |
217 | array_klass = con; // Use cast value moving forward |
218 | } |
219 | } |
220 | |
221 | // Come here for polymorphic array klasses |
222 | |
223 | // Extract the array element class |
224 | int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset()); |
225 | Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); |
226 | // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true, |
227 | // we must set a control edge from the IfTrue node created by the uncommon_trap above to the |
228 | // LoadKlassNode. |
229 | Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL__null, |
230 | immutable_memory(), p2, tak)); |
231 | |
232 | // Check (the hard way) and throw if not a subklass. |
233 | // Result is ignored, we just need the CFG effects. |
234 | gen_checkcast(obj, a_e_klass); |
235 | } |
236 | |
237 | |
238 | //------------------------------do_new----------------------------------------- |
239 | void Parse::do_new() { |
240 | kill_dead_locals(); |
241 | |
242 | bool will_link; |
243 | ciInstanceKlass* klass = iter().get_klass(will_link)->as_instance_klass(); |
244 | assert(will_link, "_new: typeflow responsibility")do { if (!(will_link)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/opto/parseHelper.cpp" , 244, "assert(" "will_link" ") failed", "_new: typeflow responsibility" ); ::breakpoint(); } } while (0); |
245 | |
246 | // Should throw an InstantiationError? |
247 | if (klass->is_abstract() || klass->is_interface() || |
248 | klass->name() == ciSymbols::java_lang_Class() || |
249 | iter().is_unresolved_klass()) { |
250 | uncommon_trap(Deoptimization::Reason_unhandled, |
251 | Deoptimization::Action_none, |
252 | klass); |
253 | return; |
254 | } |
255 | |
256 | if (C->needs_clinit_barrier(klass, method())) { |
257 | clinit_barrier(klass, method()); |
258 | if (stopped()) return; |
259 | } |
260 | |
261 | Node* kls = makecon(TypeKlassPtr::make(klass)); |
262 | Node* obj = new_instance(kls); |
263 | |
264 | // Push resultant oop onto stack |
265 | push(obj); |
266 | |
267 | // Keep track of whether opportunities exist for StringBuilder |
268 | // optimizations. |
269 | if (OptimizeStringConcat && |
270 | (klass == C->env()->StringBuilder_klass() || |
271 | klass == C->env()->StringBuffer_klass())) { |
272 | C->set_has_stringbuilder(true); |
273 | } |
274 | |
275 | // Keep track of boxed values for EliminateAutoBox optimizations. |
276 | if (C->eliminate_boxing() && klass->is_box_klass()) { |
277 | C->set_has_boxed_value(true); |
278 | } |
279 | } |
280 | |
281 | #ifndef PRODUCT |
282 | //------------------------------dump_map_adr_mem------------------------------- |
283 | // Debug dump of the mapping from address types to MergeMemNode indices. |
284 | void Parse::dump_map_adr_mem() const { |
285 | tty->print_cr("--- Mapping from address types to memory Nodes ---"); |
286 | MergeMemNode *mem = map() == NULL__null ? NULL__null : (map()->memory()->is_MergeMem() ? |
287 | map()->memory()->as_MergeMem() : NULL__null); |
288 | for (uint i = 0; i < (uint)C->num_alias_types(); i++) { |
289 | C->alias_type(i)->print_on(tty); |
290 | tty->print("\t"); |
291 | // Node mapping, if any |
292 | if (mem && i < mem->req() && mem->in(i) && mem->in(i) != mem->empty_memory()) { |
293 | mem->in(i)->dump(); |
294 | } else { |
295 | tty->cr(); |
296 | } |
297 | } |
298 | } |
299 | |
300 | #endif |
301 |