Bug Summary

File:jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp
Warning:line 728, column 32
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name c1_Canonicalizer.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp

/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp

1/*
2 * Copyright (c) 1999, 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 "c1/c1_Canonicalizer.hpp"
27#include "c1/c1_InstructionPrinter.hpp"
28#include "c1/c1_ValueStack.hpp"
29#include "ci/ciArray.hpp"
30#include "runtime/sharedRuntime.hpp"
31
32
33class PrintValueVisitor: public ValueVisitor {
34 void visit(Value* vp) {
35 (*vp)->print_line();
36 }
37};
38
39void Canonicalizer::set_canonical(Value x) {
40 assert(x != NULL, "value must exist")do { if (!(x != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 40, "assert(" "x != __null" ") failed", "value must exist")
; ::breakpoint(); } } while (0)
;
41 // Note: we can not currently substitute root nodes which show up in
42 // the instruction stream (because the instruction list is embedded
43 // in the instructions).
44 if (canonical() != x) {
45#ifndef PRODUCT
46 if (!x->has_printable_bci()) {
47 x->set_printable_bci(bci());
48 }
49#endif
50 if (PrintCanonicalization) {
51 PrintValueVisitor do_print_value;
52 canonical()->input_values_do(&do_print_value);
53 canonical()->print_line();
54 tty->print_cr("canonicalized to:");
55 x->input_values_do(&do_print_value);
56 x->print_line();
57 tty->cr();
58 }
59 assert(_canonical->type()->tag() == x->type()->tag(), "types must match")do { if (!(_canonical->type()->tag() == x->type()->
tag())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 59, "assert(" "_canonical->type()->tag() == x->type()->tag()"
") failed", "types must match"); ::breakpoint(); } } while (
0)
;
60 _canonical = x;
61 }
62}
63
64
65void Canonicalizer::move_const_to_right(Op2* x) {
66 if (x->x()->type()->is_constant() && x->is_commutative()) x->swap_operands();
67}
68
69
70void Canonicalizer::do_Op2(Op2* x) {
71 if (x->x() == x->y()) {
72 switch (x->op()) {
73 case Bytecodes::_isub: set_constant(0); return;
74 case Bytecodes::_lsub: set_constant(jlong_cast(0)); return;
75 case Bytecodes::_iand: // fall through
76 case Bytecodes::_land: // fall through
77 case Bytecodes::_ior : // fall through
78 case Bytecodes::_lor : set_canonical(x->x()); return;
79 case Bytecodes::_ixor: set_constant(0); return;
80 case Bytecodes::_lxor: set_constant(jlong_cast(0)); return;
81 default : break;
82 }
83 }
84
85 if (x->x()->type()->is_constant() && x->y()->type()->is_constant()) {
86 // do constant folding for selected operations
87 switch (x->type()->tag()) {
88 case intTag:
89 { jint a = x->x()->type()->as_IntConstant()->value();
90 jint b = x->y()->type()->as_IntConstant()->value();
91 switch (x->op()) {
92 case Bytecodes::_iadd: set_constant(a + b); return;
93 case Bytecodes::_isub: set_constant(a - b); return;
94 case Bytecodes::_imul: set_constant(a * b); return;
95 case Bytecodes::_idiv:
96 if (b != 0) {
97 if (a == min_jint && b == -1) {
98 set_constant(min_jint);
99 } else {
100 set_constant(a / b);
101 }
102 return;
103 }
104 break;
105 case Bytecodes::_irem:
106 if (b != 0) {
107 if (a == min_jint && b == -1) {
108 set_constant(0);
109 } else {
110 set_constant(a % b);
111 }
112 return;
113 }
114 break;
115 case Bytecodes::_iand: set_constant(a & b); return;
116 case Bytecodes::_ior : set_constant(a | b); return;
117 case Bytecodes::_ixor: set_constant(a ^ b); return;
118 default : break;
119 }
120 }
121 break;
122 case longTag:
123 { jlong a = x->x()->type()->as_LongConstant()->value();
124 jlong b = x->y()->type()->as_LongConstant()->value();
125 switch (x->op()) {
126 case Bytecodes::_ladd: set_constant(a + b); return;
127 case Bytecodes::_lsub: set_constant(a - b); return;
128 case Bytecodes::_lmul: set_constant(a * b); return;
129 case Bytecodes::_ldiv:
130 if (b != 0) {
131 set_constant(SharedRuntime::ldiv(b, a));
132 return;
133 }
134 break;
135 case Bytecodes::_lrem:
136 if (b != 0) {
137 set_constant(SharedRuntime::lrem(b, a));
138 return;
139 }
140 break;
141 case Bytecodes::_land: set_constant(a & b); return;
142 case Bytecodes::_lor : set_constant(a | b); return;
143 case Bytecodes::_lxor: set_constant(a ^ b); return;
144 default : break;
145 }
146 }
147 break;
148 default:
149 // other cases not implemented (must be extremely careful with floats & doubles!)
150 break;
151 }
152 }
153 // make sure constant is on the right side, if any
154 move_const_to_right(x);
155
156 if (x->y()->type()->is_constant()) {
157 // do constant folding for selected operations
158 switch (x->type()->tag()) {
159 case intTag:
160 if (x->y()->type()->as_IntConstant()->value() == 0) {
161 switch (x->op()) {
162 case Bytecodes::_iadd: set_canonical(x->x()); return;
163 case Bytecodes::_isub: set_canonical(x->x()); return;
164 case Bytecodes::_imul: set_constant(0); return;
165 // Note: for div and rem, make sure that C semantics
166 // corresponds to Java semantics!
167 case Bytecodes::_iand: set_constant(0); return;
168 case Bytecodes::_ior : set_canonical(x->x()); return;
169 default : break;
170 }
171 }
172 break;
173 case longTag:
174 if (x->y()->type()->as_LongConstant()->value() == (jlong)0) {
175 switch (x->op()) {
176 case Bytecodes::_ladd: set_canonical(x->x()); return;
177 case Bytecodes::_lsub: set_canonical(x->x()); return;
178 case Bytecodes::_lmul: set_constant((jlong)0); return;
179 // Note: for div and rem, make sure that C semantics
180 // corresponds to Java semantics!
181 case Bytecodes::_land: set_constant((jlong)0); return;
182 case Bytecodes::_lor : set_canonical(x->x()); return;
183 default : break;
184 }
185 }
186 break;
187 default:
188 break;
189 }
190 }
191}
192
193
194void Canonicalizer::do_Phi (Phi* x) {}
195void Canonicalizer::do_Constant (Constant* x) {}
196void Canonicalizer::do_Local (Local* x) {}
197void Canonicalizer::do_LoadField (LoadField* x) {}
198
199// checks if v is in the block that is currently processed by
200// GraphBuilder. This is the only block that has not BlockEnd yet.
201static bool in_current_block(Value v) {
202 int max_distance = 4;
203 while (max_distance > 0 && v != NULL__null && v->as_BlockEnd() == NULL__null) {
204 v = v->next();
205 max_distance--;
206 }
207 return v == NULL__null;
208}
209
210void Canonicalizer::do_StoreField (StoreField* x) {
211 // If a value is going to be stored into a field or array some of
212 // the conversions emitted by javac are unneeded because the fields
213 // are packed to their natural size.
214 Convert* conv = x->value()->as_Convert();
215 if (conv) {
216 Value value = NULL__null;
217 BasicType type = x->field()->type()->basic_type();
218 switch (conv->op()) {
219 case Bytecodes::_i2b: if (type == T_BYTE) value = conv->value(); break;
220 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) value = conv->value(); break;
221 case Bytecodes::_i2c: if (type == T_CHAR || type == T_BYTE) value = conv->value(); break;
222 default : break;
223 }
224 // limit this optimization to current block
225 if (value != NULL__null && in_current_block(conv)) {
226 set_canonical(new StoreField(x->obj(), x->offset(), x->field(), value, x->is_static(),
227 x->state_before(), x->needs_patching()));
228 return;
229 }
230 }
231
232}
233
234void Canonicalizer::do_ArrayLength (ArrayLength* x) {
235 NewArray* na;
236 Constant* ct;
237 LoadField* lf;
238
239 if ((na = x->array()->as_NewArray()) != NULL__null) {
240 // New arrays might have the known length.
241 // Do not use the Constant itself, but create a new Constant
242 // with same value Otherwise a Constant is live over multiple
243 // blocks without being registered in a state array.
244 Constant* length;
245 NewMultiArray* nma;
246 if (na->length() != NULL__null &&
247 (length = na->length()->as_Constant()) != NULL__null) {
248 assert(length->type()->as_IntConstant() != NULL, "array length must be integer")do { if (!(length->type()->as_IntConstant() != __null))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 248, "assert(" "length->type()->as_IntConstant() != __null"
") failed", "array length must be integer"); ::breakpoint();
} } while (0)
;
249 set_constant(length->type()->as_IntConstant()->value());
250 } else if ((nma = x->array()->as_NewMultiArray()) != NULL__null &&
251 (length = nma->dims()->at(0)->as_Constant()) != NULL__null) {
252 assert(length->type()->as_IntConstant() != NULL, "array length must be integer")do { if (!(length->type()->as_IntConstant() != __null))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 252, "assert(" "length->type()->as_IntConstant() != __null"
") failed", "array length must be integer"); ::breakpoint();
} } while (0)
;
253 set_constant(length->type()->as_IntConstant()->value());
254 }
255
256 } else if ((ct = x->array()->as_Constant()) != NULL__null) {
257 // Constant arrays have constant lengths.
258 ArrayConstant* cnst = ct->type()->as_ArrayConstant();
259 if (cnst != NULL__null) {
260 set_constant(cnst->value()->length());
261 }
262
263 } else if ((lf = x->array()->as_LoadField()) != NULL__null) {
264 ciField* field = lf->field();
265 if (field->is_static_constant()) {
266 // Constant field loads are usually folded during parsing.
267 // But it doesn't happen with PatchALot, ScavengeRootsInCode < 2, or when
268 // holder class is being initialized during parsing (for static fields).
269 ciObject* c = field->constant_value().as_object();
270 if (!c->is_null_object()) {
271 set_constant(c->as_array()->length());
272 }
273 }
274 }
275}
276
277void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {
278 StableArrayConstant* array = x->array()->type()->as_StableArrayConstant();
279 IntConstant* index = x->index()->type()->as_IntConstant();
280
281 assert(array == NULL || FoldStableValues, "not enabled")do { if (!(array == __null || FoldStableValues)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 281, "assert(" "array == __null || FoldStableValues" ") failed"
, "not enabled"); ::breakpoint(); } } while (0)
;
282
283 // Constant fold loads from stable arrays.
284 if (!x->mismatched() && array != NULL__null && index != NULL__null) {
285 jint idx = index->value();
286 if (idx < 0 || idx >= array->value()->length()) {
287 // Leave the load as is. The range check will handle it.
288 return;
289 }
290
291 ciConstant field_val = array->value()->element_value(idx);
292 if (!field_val.is_null_or_zero()) {
293 jint dimension = array->dimension();
294 assert(dimension <= array->value()->array_type()->dimension(), "inconsistent info")do { if (!(dimension <= array->value()->array_type()
->dimension())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 294, "assert(" "dimension <= array->value()->array_type()->dimension()"
") failed", "inconsistent info"); ::breakpoint(); } } while (
0)
;
295 ValueType* value = NULL__null;
296 if (dimension > 1) {
297 // Preserve information about the dimension for the element.
298 assert(field_val.as_object()->is_array(), "not an array")do { if (!(field_val.as_object()->is_array())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 298, "assert(" "field_val.as_object()->is_array()" ") failed"
, "not an array"); ::breakpoint(); } } while (0)
;
299 value = new StableArrayConstant(field_val.as_object()->as_array(), dimension - 1);
300 } else {
301 assert(dimension == 1, "sanity")do { if (!(dimension == 1)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 301, "assert(" "dimension == 1" ") failed", "sanity"); ::breakpoint
(); } } while (0)
;
302 value = as_ValueType(field_val);
303 }
304 set_canonical(new Constant(value));
305 }
306 }
307}
308
309void Canonicalizer::do_StoreIndexed (StoreIndexed* x) {
310 // If a value is going to be stored into a field or array some of
311 // the conversions emitted by javac are unneeded because the fields
312 // are packed to their natural size.
313 Convert* conv = x->value()->as_Convert();
314 if (conv) {
315 Value value = NULL__null;
316 BasicType type = x->elt_type();
317 switch (conv->op()) {
318 case Bytecodes::_i2b: if (type == T_BYTE) value = conv->value(); break;
319 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) value = conv->value(); break;
320 case Bytecodes::_i2c: if (type == T_CHAR || type == T_BYTE) value = conv->value(); break;
321 default : break;
322 }
323 // limit this optimization to current block
324 if (value != NULL__null && in_current_block(conv)) {
325 set_canonical(new StoreIndexed(x->array(), x->index(), x->length(),
326 x->elt_type(), value, x->state_before(),
327 x->check_boolean()));
328 return;
329 }
330 }
331}
332
333
334void Canonicalizer::do_NegateOp(NegateOp* x) {
335 ValueType* t = x->x()->type();
336 if (t->is_constant()) {
337 switch (t->tag()) {
338 case intTag : set_constant(-t->as_IntConstant ()->value()); return;
339 case longTag : set_constant(-t->as_LongConstant ()->value()); return;
340 case floatTag : set_constant(-t->as_FloatConstant ()->value()); return;
341 case doubleTag: set_constant(-t->as_DoubleConstant()->value()); return;
342 default : ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 342); ::breakpoint(); } while (0)
;
343 }
344 }
345}
346
347
348void Canonicalizer::do_ArithmeticOp (ArithmeticOp* x) { do_Op2(x); }
349
350
351void Canonicalizer::do_ShiftOp (ShiftOp* x) {
352 ValueType* t = x->x()->type();
353 ValueType* t2 = x->y()->type();
354 if (t->is_constant()) {
355 switch (t->tag()) {
356 case intTag : if (t->as_IntConstant()->value() == 0) { set_constant(0); return; } break;
357 case longTag : if (t->as_LongConstant()->value() == (jlong)0) { set_constant(jlong_cast(0)); return; } break;
358 default : ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 358); ::breakpoint(); } while (0)
;
359 }
360 if (t2->is_constant()) {
361 if (t->tag() == intTag) {
362 jint value = t->as_IntConstant()->value();
363 jint shift = t2->as_IntConstant()->value();
364 switch (x->op()) {
365 case Bytecodes::_ishl: set_constant(java_shift_left(value, shift)); return;
366 case Bytecodes::_ishr: set_constant(java_shift_right(value, shift)); return;
367 case Bytecodes::_iushr: set_constant(java_shift_right_unsigned(value, shift)); return;
368 default: break;
369 }
370 } else if (t->tag() == longTag) {
371 jlong value = t->as_LongConstant()->value();
372 jint shift = t2->as_IntConstant()->value();
373 switch (x->op()) {
374 case Bytecodes::_lshl: set_constant(java_shift_left(value, shift)); return;
375 case Bytecodes::_lshr: set_constant(java_shift_right(value, shift)); return;
376 case Bytecodes::_lushr: set_constant(java_shift_right_unsigned(value, shift)); return;
377 default: break;
378 }
379 }
380 }
381 }
382 if (t2->is_constant()) {
383 switch (t2->tag()) {
384 case intTag : if (t2->as_IntConstant()->value() == 0) set_canonical(x->x()); return;
385 case longTag : if (t2->as_LongConstant()->value() == (jlong)0) set_canonical(x->x()); return;
386 default : ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 386); ::breakpoint(); } while (0)
; return;
387 }
388 }
389}
390
391
392void Canonicalizer::do_LogicOp (LogicOp* x) { do_Op2(x); }
393void Canonicalizer::do_CompareOp (CompareOp* x) {
394 if (x->x() == x->y()) {
395 switch (x->x()->type()->tag()) {
396 case longTag: set_constant(0); break;
397 case floatTag: {
398 FloatConstant* fc = x->x()->type()->as_FloatConstant();
399 if (fc) {
400 if (g_isnan(fc->value())) {
401 set_constant(x->op() == Bytecodes::_fcmpl ? -1 : 1);
402 } else {
403 set_constant(0);
404 }
405 }
406 break;
407 }
408 case doubleTag: {
409 DoubleConstant* dc = x->x()->type()->as_DoubleConstant();
410 if (dc) {
411 if (g_isnan(dc->value())) {
412 set_constant(x->op() == Bytecodes::_dcmpl ? -1 : 1);
413 } else {
414 set_constant(0);
415 }
416 }
417 break;
418 }
419 default:
420 break;
421 }
422 } else if (x->x()->type()->is_constant() && x->y()->type()->is_constant()) {
423 switch (x->x()->type()->tag()) {
424 case longTag: {
425 jlong vx = x->x()->type()->as_LongConstant()->value();
426 jlong vy = x->y()->type()->as_LongConstant()->value();
427 if (vx == vy)
428 set_constant(0);
429 else if (vx < vy)
430 set_constant(-1);
431 else
432 set_constant(1);
433 break;
434 }
435
436 case floatTag: {
437 float vx = x->x()->type()->as_FloatConstant()->value();
438 float vy = x->y()->type()->as_FloatConstant()->value();
439 if (g_isnan(vx) || g_isnan(vy))
440 set_constant(x->op() == Bytecodes::_fcmpl ? -1 : 1);
441 else if (vx == vy)
442 set_constant(0);
443 else if (vx < vy)
444 set_constant(-1);
445 else
446 set_constant(1);
447 break;
448 }
449
450 case doubleTag: {
451 double vx = x->x()->type()->as_DoubleConstant()->value();
452 double vy = x->y()->type()->as_DoubleConstant()->value();
453 if (g_isnan(vx) || g_isnan(vy))
454 set_constant(x->op() == Bytecodes::_dcmpl ? -1 : 1);
455 else if (vx == vy)
456 set_constant(0);
457 else if (vx < vy)
458 set_constant(-1);
459 else
460 set_constant(1);
461 break;
462 }
463
464 default:
465 break;
466 }
467 }
468}
469
470
471void Canonicalizer::do_IfOp(IfOp* x) {
472 // Caution: do not use do_Op2(x) here for now since
473 // we map the condition to the op for now!
474 move_const_to_right(x);
475}
476
477
478void Canonicalizer::do_Intrinsic (Intrinsic* x) {
479 switch (x->id()) {
480 case vmIntrinsics::_floatToRawIntBits : {
481 FloatConstant* c = x->argument_at(0)->type()->as_FloatConstant();
482 if (c != NULL__null) {
483 JavaValue v;
484 v.set_jfloat(c->value());
485 set_constant(v.get_jint());
486 }
487 break;
488 }
489 case vmIntrinsics::_intBitsToFloat : {
490 IntConstant* c = x->argument_at(0)->type()->as_IntConstant();
491 if (c != NULL__null) {
492 JavaValue v;
493 v.set_jint(c->value());
494 set_constant(v.get_jfloat());
495 }
496 break;
497 }
498 case vmIntrinsics::_doubleToRawLongBits : {
499 DoubleConstant* c = x->argument_at(0)->type()->as_DoubleConstant();
500 if (c != NULL__null) {
501 JavaValue v;
502 v.set_jdouble(c->value());
503 set_constant(v.get_jlong());
504 }
505 break;
506 }
507 case vmIntrinsics::_longBitsToDouble : {
508 LongConstant* c = x->argument_at(0)->type()->as_LongConstant();
509 if (c != NULL__null) {
510 JavaValue v;
511 v.set_jlong(c->value());
512 set_constant(v.get_jdouble());
513 }
514 break;
515 }
516 case vmIntrinsics::_isInstance : {
517 assert(x->number_of_arguments() == 2, "wrong type")do { if (!(x->number_of_arguments() == 2)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 517, "assert(" "x->number_of_arguments() == 2" ") failed"
, "wrong type"); ::breakpoint(); } } while (0)
;
518
519 InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant();
520 if (c != NULL__null && !c->value()->is_null_object()) {
521 // ciInstance::java_mirror_type() returns non-NULL only for Java mirrors
522 ciType* t = c->value()->java_mirror_type();
523 if (t->is_klass()) {
524 // substitute cls.isInstance(obj) of a constant Class into
525 // an InstantOf instruction
526 InstanceOf* i = new InstanceOf(t->as_klass(), x->argument_at(1), x->state_before());
527 set_canonical(i);
528 // and try to canonicalize even further
529 do_InstanceOf(i);
530 } else {
531 assert(t->is_primitive_type(), "should be a primitive type")do { if (!(t->is_primitive_type())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 531, "assert(" "t->is_primitive_type()" ") failed", "should be a primitive type"
); ::breakpoint(); } } while (0)
;
532 // cls.isInstance(obj) always returns false for primitive classes
533 set_constant(0);
534 }
535 }
536 break;
537 }
538 case vmIntrinsics::_isPrimitive : {
539 assert(x->number_of_arguments() == 1, "wrong type")do { if (!(x->number_of_arguments() == 1)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 539, "assert(" "x->number_of_arguments() == 1" ") failed"
, "wrong type"); ::breakpoint(); } } while (0)
;
540
541 // Class.isPrimitive is known on constant classes:
542 InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant();
543 if (c != NULL__null && !c->value()->is_null_object()) {
544 ciType* t = c->value()->java_mirror_type();
545 set_constant(t->is_primitive_type());
546 }
547 break;
548 }
549 case vmIntrinsics::_getModifiers: {
550 assert(x->number_of_arguments() == 1, "wrong type")do { if (!(x->number_of_arguments() == 1)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 550, "assert(" "x->number_of_arguments() == 1" ") failed"
, "wrong type"); ::breakpoint(); } } while (0)
;
551
552 // Optimize for Foo.class.getModifier()
553 InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant();
554 if (c != NULL__null && !c->value()->is_null_object()) {
555 ciType* t = c->value()->java_mirror_type();
556 if (t->is_klass()) {
557 set_constant(t->as_klass()->modifier_flags());
558 } else {
559 assert(t->is_primitive_type(), "should be a primitive type")do { if (!(t->is_primitive_type())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 559, "assert(" "t->is_primitive_type()" ") failed", "should be a primitive type"
); ::breakpoint(); } } while (0)
;
560 set_constant(JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
561 }
562 }
563 break;
564 }
565 default:
566 break;
567 }
568}
569
570void Canonicalizer::do_Convert (Convert* x) {
571 if (x->value()->type()->is_constant()) {
572 switch (x->op()) {
573 case Bytecodes::_i2b: set_constant((int)((x->value()->type()->as_IntConstant()->value() << 24) >> 24)); break;
574 case Bytecodes::_i2s: set_constant((int)((x->value()->type()->as_IntConstant()->value() << 16) >> 16)); break;
575 case Bytecodes::_i2c: set_constant((int)(x->value()->type()->as_IntConstant()->value() & ((1<<16)-1))); break;
576 case Bytecodes::_i2l: set_constant((jlong)(x->value()->type()->as_IntConstant()->value())); break;
577 case Bytecodes::_i2f: set_constant((float)(x->value()->type()->as_IntConstant()->value())); break;
578 case Bytecodes::_i2d: set_constant((double)(x->value()->type()->as_IntConstant()->value())); break;
579 case Bytecodes::_l2i: set_constant((int)(x->value()->type()->as_LongConstant()->value())); break;
580 case Bytecodes::_l2f: set_constant(SharedRuntime::l2f(x->value()->type()->as_LongConstant()->value())); break;
581 case Bytecodes::_l2d: set_constant(SharedRuntime::l2d(x->value()->type()->as_LongConstant()->value())); break;
582 case Bytecodes::_f2d: set_constant((double)(x->value()->type()->as_FloatConstant()->value())); break;
583 case Bytecodes::_f2i: set_constant(SharedRuntime::f2i(x->value()->type()->as_FloatConstant()->value())); break;
584 case Bytecodes::_f2l: set_constant(SharedRuntime::f2l(x->value()->type()->as_FloatConstant()->value())); break;
585 case Bytecodes::_d2f: set_constant((float)(x->value()->type()->as_DoubleConstant()->value())); break;
586 case Bytecodes::_d2i: set_constant(SharedRuntime::d2i(x->value()->type()->as_DoubleConstant()->value())); break;
587 case Bytecodes::_d2l: set_constant(SharedRuntime::d2l(x->value()->type()->as_DoubleConstant()->value())); break;
588 default:
589 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 589); ::breakpoint(); } while (0)
;
590 }
591 }
592
593 Value value = x->value();
594 BasicType type = T_ILLEGAL;
595 LoadField* lf = value->as_LoadField();
596 if (lf) {
597 type = lf->field_type();
598 } else {
599 LoadIndexed* li = value->as_LoadIndexed();
600 if (li) {
601 type = li->elt_type();
602 } else {
603 Convert* conv = value->as_Convert();
604 if (conv) {
605 switch (conv->op()) {
606 case Bytecodes::_i2b: type = T_BYTE; break;
607 case Bytecodes::_i2s: type = T_SHORT; break;
608 case Bytecodes::_i2c: type = T_CHAR; break;
609 default : break;
610 }
611 }
612 }
613 }
614 if (type != T_ILLEGAL) {
615 switch (x->op()) {
616 case Bytecodes::_i2b: if (type == T_BYTE) set_canonical(x->value()); break;
617 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) set_canonical(x->value()); break;
618 case Bytecodes::_i2c: if (type == T_CHAR) set_canonical(x->value()); break;
619 default : break;
620 }
621 } else {
622 Op2* op2 = x->value()->as_Op2();
623 if (op2 && op2->op() == Bytecodes::_iand && op2->y()->type()->is_constant()) {
624 jint safebits = 0;
625 jint mask = op2->y()->type()->as_IntConstant()->value();
626 switch (x->op()) {
627 case Bytecodes::_i2b: safebits = 0x7f; break;
628 case Bytecodes::_i2s: safebits = 0x7fff; break;
629 case Bytecodes::_i2c: safebits = 0xffff; break;
630 default : break;
631 }
632 // When casting a masked integer to a smaller signed type, if
633 // the mask doesn't include the sign bit the cast isn't needed.
634 if (safebits && (mask & ~safebits) == 0) {
635 set_canonical(x->value());
636 }
637 }
638 }
639
640}
641
642void Canonicalizer::do_NullCheck (NullCheck* x) {
643 if (x->obj()->as_NewArray() != NULL__null || x->obj()->as_NewInstance() != NULL__null) {
644 set_canonical(x->obj());
645 } else {
646 Constant* con = x->obj()->as_Constant();
647 if (con) {
648 ObjectType* c = con->type()->as_ObjectType();
649 if (c && c->is_loaded()) {
650 ObjectConstant* oc = c->as_ObjectConstant();
651 if (!oc || !oc->value()->is_null_object()) {
652 set_canonical(con);
653 }
654 }
655 }
656 }
657}
658
659void Canonicalizer::do_TypeCast (TypeCast* x) {}
660void Canonicalizer::do_Invoke (Invoke* x) {}
661void Canonicalizer::do_NewInstance (NewInstance* x) {}
662void Canonicalizer::do_NewTypeArray (NewTypeArray* x) {}
663void Canonicalizer::do_NewObjectArray (NewObjectArray* x) {}
664void Canonicalizer::do_NewMultiArray (NewMultiArray* x) {}
665void Canonicalizer::do_CheckCast (CheckCast* x) {
666 if (x->klass()->is_loaded()) {
667 Value obj = x->obj();
668 ciType* klass = obj->exact_type();
669 if (klass == NULL__null) {
670 klass = obj->declared_type();
671 }
672 if (klass != NULL__null && klass->is_loaded()) {
673 bool is_interface = klass->is_instance_klass() &&
674 klass->as_instance_klass()->is_interface();
675 // Interface casts can't be statically optimized away since verifier doesn't
676 // enforce interface types in bytecode.
677 if (!is_interface && klass->is_subtype_of(x->klass())) {
678 set_canonical(obj);
679 return;
680 }
681 }
682 // checkcast of null returns null
683 if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) {
684 set_canonical(obj);
685 }
686 }
687}
688void Canonicalizer::do_InstanceOf (InstanceOf* x) {
689 if (x->klass()->is_loaded()) {
690 Value obj = x->obj();
691 ciType* exact = obj->exact_type();
692 if (exact != NULL__null && exact->is_loaded() && (obj->as_NewInstance() || obj->as_NewArray())) {
693 set_constant(exact->is_subtype_of(x->klass()) ? 1 : 0);
694 return;
695 }
696 // instanceof null returns false
697 if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) {
698 set_constant(0);
699 }
700 }
701
702}
703void Canonicalizer::do_MonitorEnter (MonitorEnter* x) {}
704void Canonicalizer::do_MonitorExit (MonitorExit* x) {}
705void Canonicalizer::do_BlockBegin (BlockBegin* x) {}
706void Canonicalizer::do_Goto (Goto* x) {}
707
708
709static bool is_true(jlong x, If::Condition cond, jlong y) {
710 switch (cond) {
711 case If::eql: return x == y;
712 case If::neq: return x != y;
713 case If::lss: return x < y;
714 case If::leq: return x <= y;
715 case If::gtr: return x > y;
716 case If::geq: return x >= y;
717 default:
718 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 718); ::breakpoint(); } while (0)
;
719 return false;
720 }
721}
722
723static bool is_safepoint(BlockEnd* x, BlockBegin* sux) {
724 // An Instruction with multiple successors, x, is replaced by a Goto
725 // to a single successor, sux. Is a safepoint check needed = was the
726 // instruction being replaced a safepoint and the single remaining
727 // successor a back branch?
728 return x->is_safepoint() && (sux->bci() < x->state_before()->bci());
15
Assuming the condition is true
16
Called C++ object pointer is null
729}
730
731void Canonicalizer::do_If(If* x) {
732 // move const to right
733 if (x->x()->type()->is_constant()) x->swap_operands();
1
Assuming the condition is false
2
Taking false branch
734 // simplify
735 const Value l = x->x(); ValueType* lt = l->type();
736 const Value r = x->y(); ValueType* rt = r->type();
737
738 if (l == r && !lt->is_float_kind()) {
3
Assuming 'l' is equal to 'r'
4
Calling 'ValueType::is_float_kind'
8
Returning from 'ValueType::is_float_kind'
9
Taking true branch
739 // pattern: If (a cond a) => simplify to Goto
740 BlockBegin* sux = NULL__null;
10
'sux' initialized to a null pointer value
741 switch (x->cond()) {
11
Control jumps to the 'default' case at line 748
742 case If::eql: sux = x->sux_for(true); break;
743 case If::neq: sux = x->sux_for(false); break;
744 case If::lss: sux = x->sux_for(false); break;
745 case If::leq: sux = x->sux_for(true); break;
746 case If::gtr: sux = x->sux_for(false); break;
747 case If::geq: sux = x->sux_for(true); break;
748 default: ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 748); ::breakpoint(); } while (0)
;
12
Loop condition is false. Exiting loop
749 }
750 // If is a safepoint then the debug information should come from the state_before of the If.
751 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
13
Passing null pointer value via 2nd parameter 'sux'
14
Calling 'is_safepoint'
752 return;
753 }
754
755 if (lt->is_constant() && rt->is_constant()) {
756 if (x->x()->as_Constant() != NULL__null) {
757 // pattern: If (lc cond rc) => simplify to: Goto
758 BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(),
759 x->sux_for(true),
760 x->sux_for(false));
761 if (sux != NULL__null) {
762 // If is a safepoint then the debug information should come from the state_before of the If.
763 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
764 }
765 }
766 } else if (rt->as_IntConstant() != NULL__null) {
767 // pattern: If (l cond rc) => investigate further
768 const jint rc = rt->as_IntConstant()->value();
769 if (l->as_CompareOp() != NULL__null) {
770 // pattern: If ((a cmp b) cond rc) => simplify to: If (x cond y) or: Goto
771 CompareOp* cmp = l->as_CompareOp();
772 bool unordered_is_less = cmp->op() == Bytecodes::_fcmpl || cmp->op() == Bytecodes::_dcmpl;
773 BlockBegin* lss_sux = x->sux_for(is_true(-1, x->cond(), rc)); // successor for a < b
774 BlockBegin* eql_sux = x->sux_for(is_true( 0, x->cond(), rc)); // successor for a = b
775 BlockBegin* gtr_sux = x->sux_for(is_true(+1, x->cond(), rc)); // successor for a > b
776 BlockBegin* nan_sux = unordered_is_less ? lss_sux : gtr_sux ; // successor for unordered
777 // Note: At this point all successors (lss_sux, eql_sux, gtr_sux, nan_sux) are
778 // equal to x->tsux() or x->fsux(). Furthermore, nan_sux equals either
779 // lss_sux or gtr_sux.
780 if (lss_sux == eql_sux && eql_sux == gtr_sux) {
781 // all successors identical => simplify to: Goto
782 set_canonical(new Goto(lss_sux, x->state_before(), x->is_safepoint()));
783 } else {
784 // two successors differ and two successors are the same => simplify to: If (x cmp y)
785 // determine new condition & successors
786 If::Condition cond = If::eql;
787 BlockBegin* tsux = NULL__null;
788 BlockBegin* fsux = NULL__null;
789 if (lss_sux == eql_sux) { cond = If::leq; tsux = lss_sux; fsux = gtr_sux; }
790 else if (lss_sux == gtr_sux) { cond = If::neq; tsux = lss_sux; fsux = eql_sux; }
791 else if (eql_sux == gtr_sux) { cond = If::geq; tsux = eql_sux; fsux = lss_sux; }
792 else { ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 792); ::breakpoint(); } while (0)
; }
793 If* canon = new If(cmp->x(), cond, nan_sux == tsux, cmp->y(), tsux, fsux, cmp->state_before(), x->is_safepoint());
794 if (cmp->x() == cmp->y()) {
795 do_If(canon);
796 } else {
797 if (compilation()->profile_branches() || compilation()->is_profiling()) {
798 // TODO: If profiling, leave floating point comparisons unoptimized.
799 // We currently do not support profiling of the unordered case.
800 switch(cmp->op()) {
801 case Bytecodes::_fcmpl: case Bytecodes::_fcmpg:
802 case Bytecodes::_dcmpl: case Bytecodes::_dcmpg:
803 set_canonical(x);
804 return;
805 default:
806 break;
807 }
808 }
809 set_bci(cmp->state_before()->bci());
810 set_canonical(canon);
811 }
812 }
813 }
814 } else if (rt == objectNull &&
815 (l->as_NewInstance() || l->as_NewArray() ||
816 (l->as_Local() && l->as_Local()->is_receiver()))) {
817 if (x->cond() == Instruction::eql) {
818 BlockBegin* sux = x->fsux();
819 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
820 } else {
821 assert(x->cond() == Instruction::neq, "only other valid case")do { if (!(x->cond() == Instruction::neq)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_Canonicalizer.cpp"
, 821, "assert(" "x->cond() == Instruction::neq" ") failed"
, "only other valid case"); ::breakpoint(); } } while (0)
;
822 BlockBegin* sux = x->tsux();
823 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
824 }
825 }
826}
827
828
829void Canonicalizer::do_TableSwitch(TableSwitch* x) {
830 if (x->tag()->type()->is_constant()) {
831 int v = x->tag()->type()->as_IntConstant()->value();
832 BlockBegin* sux = x->default_sux();
833 if (v >= x->lo_key() && v <= x->hi_key()) {
834 sux = x->sux_at(v - x->lo_key());
835 }
836 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
837 }
838}
839
840
841void Canonicalizer::do_LookupSwitch(LookupSwitch* x) {
842 if (x->tag()->type()->is_constant()) {
843 int v = x->tag()->type()->as_IntConstant()->value();
844 BlockBegin* sux = x->default_sux();
845 for (int i = 0; i < x->length(); i++) {
846 if (v == x->key_at(i)) {
847 sux = x->sux_at(i);
848 }
849 }
850 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
851 }
852}
853
854
855void Canonicalizer::do_Return (Return* x) {}
856void Canonicalizer::do_Throw (Throw* x) {}
857void Canonicalizer::do_Base (Base* x) {}
858void Canonicalizer::do_OsrEntry (OsrEntry* x) {}
859void Canonicalizer::do_ExceptionObject(ExceptionObject* x) {}
860void Canonicalizer::do_RoundFP (RoundFP* x) {}
861void Canonicalizer::do_UnsafeGet (UnsafeGet* x) {}
862void Canonicalizer::do_UnsafePut (UnsafePut* x) {}
863void Canonicalizer::do_UnsafeGetAndSet(UnsafeGetAndSet* x) {}
864void Canonicalizer::do_ProfileCall (ProfileCall* x) {}
865void Canonicalizer::do_ProfileReturnType(ProfileReturnType* x) {}
866void Canonicalizer::do_ProfileInvoke (ProfileInvoke* x) {}
867void Canonicalizer::do_RuntimeCall (RuntimeCall* x) {}
868void Canonicalizer::do_RangeCheckPredicate(RangeCheckPredicate* x) {}
869#ifdef ASSERT1
870void Canonicalizer::do_Assert (Assert* x) {}
871#endif
872void Canonicalizer::do_MemBar (MemBar* x) {}

/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_ValueType.hpp

1/*
2 * Copyright (c) 1999, 2019, 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#ifndef SHARE_C1_C1_VALUETYPE_HPP
26#define SHARE_C1_C1_VALUETYPE_HPP
27
28#include "c1/c1_Compilation.hpp"
29#include "ci/ciConstant.hpp"
30#include "ci/ciMethodData.hpp"
31
32// type hierarchy
33class ValueType;
34class VoidType;
35class IntType;
36class IntConstant;
37class LongType;
38class LongConstant;
39class FloatType;
40class FloatConstant;
41class DoubleType;
42class DoubleConstant;
43class ObjectType;
44class ObjectConstant;
45class ArrayType;
46class ArrayConstant;
47class StableArrayConstant;
48class InstanceType;
49class InstanceConstant;
50class MetadataType;
51class ClassType;
52class ClassConstant;
53class MethodType;
54class MethodConstant;
55class AddressType;
56class AddressConstant;
57class IllegalType;
58
59
60// predefined types
61extern VoidType* voidType;
62extern IntType* intType;
63extern LongType* longType;
64extern FloatType* floatType;
65extern DoubleType* doubleType;
66extern ObjectType* objectType;
67extern ArrayType* arrayType;
68extern InstanceType* instanceType;
69extern ClassType* classType;
70extern AddressType* addressType;
71extern IllegalType* illegalType;
72
73
74// predefined constants
75extern IntConstant* intZero;
76extern IntConstant* intOne;
77extern ObjectConstant* objectNull;
78
79
80// tags
81enum ValueTag {
82 // all legal tags must come first
83 intTag,
84 longTag,
85 floatTag,
86 doubleTag,
87 objectTag,
88 addressTag,
89 metaDataTag,
90 number_of_legal_tags,
91 // all other tags must follow afterwards
92 voidTag = number_of_legal_tags,
93 illegalTag,
94 number_of_tags
95};
96
97
98class ValueType: public CompilationResourceObj {
99 private:
100 const int _size;
101 const ValueTag _tag;
102 ValueType();
103 protected:
104 ValueType(ValueTag tag, int size): _size(size), _tag(tag) {}
105
106 public:
107 // initialization
108 static void initialize(Arena* arena);
109
110 // accessors
111 virtual ValueType* base() const = 0; // the 'canonical' type (e.g., intType for an IntConstant)
112 ValueTag tag() const { return _tag; } // the 'canonical' tag (useful for type matching)
113 int size() const { // the size of an object of the type in words
114 assert(_size > -1, "shouldn't be asking for size")do { if (!(_size > -1)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_ValueType.hpp"
, 114, "assert(" "_size > -1" ") failed", "shouldn't be asking for size"
); ::breakpoint(); } } while (0)
;
115 return _size;
116 }
117 virtual const char tchar() const = 0; // the type 'character' for printing
118 virtual const char* name() const = 0; // the type name for printing
119 virtual bool is_constant() const { return false; }
120
121 // testers
122 bool is_void() { return tag() == voidTag; }
123 bool is_int() { return tag() == intTag; }
124 bool is_long() { return tag() == longTag; }
125 bool is_float() { return tag() == floatTag; }
126 bool is_double() { return tag() == doubleTag; }
127 bool is_object() { return as_ObjectType() != NULL__null; }
128 bool is_array() { return as_ArrayType() != NULL__null; }
129 bool is_instance() { return as_InstanceType() != NULL__null; }
130 bool is_class() { return as_ClassType() != NULL__null; }
131 bool is_method() { return as_MethodType() != NULL__null; }
132 bool is_address() { return as_AddressType() != NULL__null; }
133 bool is_illegal() { return tag() == illegalTag; }
134
135 bool is_int_kind() const { return tag() == intTag || tag() == longTag; }
136 bool is_float_kind() const { return tag() == floatTag || tag() == doubleTag; }
5
Assuming the condition is false
6
Assuming the condition is false
7
Returning zero, which participates in a condition later
137 bool is_object_kind() const { return tag() == objectTag; }
138
139 bool is_single_word() const { return _size == 1; }
140 bool is_double_word() const { return _size == 2; }
141
142 // casting
143 virtual VoidType* as_VoidType() { return NULL__null; }
144 virtual IntType* as_IntType() { return NULL__null; }
145 virtual LongType* as_LongType() { return NULL__null; }
146 virtual FloatType* as_FloatType() { return NULL__null; }
147 virtual DoubleType* as_DoubleType() { return NULL__null; }
148 virtual ObjectType* as_ObjectType() { return NULL__null; }
149 virtual ArrayType* as_ArrayType() { return NULL__null; }
150 virtual InstanceType* as_InstanceType() { return NULL__null; }
151 virtual ClassType* as_ClassType() { return NULL__null; }
152 virtual MetadataType* as_MetadataType() { return NULL__null; }
153 virtual MethodType* as_MethodType() { return NULL__null; }
154 virtual AddressType* as_AddressType() { return NULL__null; }
155 virtual IllegalType* as_IllegalType() { return NULL__null; }
156 virtual IntConstant* as_IntConstant() { return NULL__null; }
157 virtual LongConstant* as_LongConstant() { return NULL__null; }
158 virtual FloatConstant* as_FloatConstant() { return NULL__null; }
159 virtual DoubleConstant* as_DoubleConstant() { return NULL__null; }
160 virtual ObjectConstant* as_ObjectConstant() { return NULL__null; }
161 virtual InstanceConstant* as_InstanceConstant(){ return NULL__null; }
162 virtual ClassConstant* as_ClassConstant() { return NULL__null; }
163 virtual MethodConstant* as_MethodConstant() { return NULL__null; }
164 virtual ArrayConstant* as_ArrayConstant() { return NULL__null; }
165 virtual StableArrayConstant* as_StableArrayConstant() { return NULL__null; }
166 virtual AddressConstant* as_AddressConstant() { return NULL__null; }
167
168 // type operations
169 ValueType* meet(ValueType* y) const;
170
171 // debugging
172 void print(outputStream* s = tty) { s->print("%s", name()); }
173};
174
175
176class VoidType: public ValueType {
177 public:
178 VoidType(): ValueType(voidTag, 0) {}
179 virtual ValueType* base() const { return voidType; }
180 virtual const char tchar() const { return 'v'; }
181 virtual const char* name() const { return "void"; }
182 virtual VoidType* as_VoidType() { return this; }
183};
184
185
186class IntType: public ValueType {
187 public:
188 IntType(): ValueType(intTag, 1) {}
189 virtual ValueType* base() const { return intType; }
190 virtual const char tchar() const { return 'i'; }
191 virtual const char* name() const { return "int"; }
192 virtual IntType* as_IntType() { return this; }
193};
194
195
196class IntConstant: public IntType {
197 private:
198 jint _value;
199
200 public:
201 IntConstant(jint value) { _value = value; }
202
203 jint value() const { return _value; }
204
205 virtual bool is_constant() const { return true; }
206 virtual IntConstant* as_IntConstant() { return this; }
207};
208
209
210class LongType: public ValueType {
211 public:
212 LongType(): ValueType(longTag, 2) {}
213 virtual ValueType* base() const { return longType; }
214 virtual const char tchar() const { return 'l'; }
215 virtual const char* name() const { return "long"; }
216 virtual LongType* as_LongType() { return this; }
217};
218
219
220class LongConstant: public LongType {
221 private:
222 jlong _value;
223
224 public:
225 LongConstant(jlong value) { _value = value; }
226
227 jlong value() const { return _value; }
228
229 virtual bool is_constant() const { return true; }
230 virtual LongConstant* as_LongConstant() { return this; }
231};
232
233
234class FloatType: public ValueType {
235 public:
236 FloatType(): ValueType(floatTag, 1) {}
237 virtual ValueType* base() const { return floatType; }
238 virtual const char tchar() const { return 'f'; }
239 virtual const char* name() const { return "float"; }
240 virtual FloatType* as_FloatType() { return this; }
241};
242
243
244class FloatConstant: public FloatType {
245 private:
246 jfloat _value;
247
248 public:
249 FloatConstant(jfloat value) { _value = value; }
250
251 jfloat value() const { return _value; }
252
253 virtual bool is_constant() const { return true; }
254 virtual FloatConstant* as_FloatConstant() { return this; }
255};
256
257
258class DoubleType: public ValueType {
259 public:
260 DoubleType(): ValueType(doubleTag, 2) {}
261 virtual ValueType* base() const { return doubleType; }
262 virtual const char tchar() const { return 'd'; }
263 virtual const char* name() const { return "double"; }
264 virtual DoubleType* as_DoubleType() { return this; }
265};
266
267
268class DoubleConstant: public DoubleType {
269 private:
270 jdouble _value;
271
272 public:
273 DoubleConstant(jdouble value) { _value = value; }
274
275 jdouble value() const { return _value; }
276
277 virtual bool is_constant() const { return true; }
278 virtual DoubleConstant* as_DoubleConstant() { return this; }
279};
280
281
282class ObjectType: public ValueType {
283 public:
284 ObjectType(): ValueType(objectTag, 1) {}
285 virtual ValueType* base() const { return objectType; }
286 virtual const char tchar() const { return 'a'; }
287 virtual const char* name() const { return "object"; }
288 virtual ObjectType* as_ObjectType() { return this; }
289 virtual ciObject* constant_value() const { ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_ValueType.hpp"
, 289); ::breakpoint(); } while (0)
; return NULL__null; }
290 virtual ciType* exact_type() const { return NULL__null; }
291 bool is_loaded() const;
292 jobject encoding() const;
293};
294
295
296class ObjectConstant: public ObjectType {
297 private:
298 ciObject* _value;
299
300 public:
301 ObjectConstant(ciObject* value) { _value = value; }
302
303 ciObject* value() const { return _value; }
304
305 virtual bool is_constant() const { return true; }
306 virtual ObjectConstant* as_ObjectConstant() { return this; }
307 virtual ciObject* constant_value() const;
308 virtual ciType* exact_type() const;
309};
310
311
312class ArrayType: public ObjectType {
313 public:
314 virtual ArrayType* as_ArrayType() { return this; }
315};
316
317
318class ArrayConstant: public ArrayType {
319 private:
320 ciArray* _value;
321
322 public:
323 ArrayConstant(ciArray* value) { _value = value; }
324
325 ciArray* value() const { return _value; }
326
327 virtual bool is_constant() const { return true; }
328 virtual ArrayConstant* as_ArrayConstant() { return this; }
329 virtual ciObject* constant_value() const;
330 virtual ciType* exact_type() const;
331};
332
333class StableArrayConstant: public ArrayConstant {
334 private:
335 jint _dimension;
336
337 public:
338 StableArrayConstant(ciArray* value, jint dimension) : ArrayConstant(value) {
339 assert(dimension > 0, "not a stable array")do { if (!(dimension > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_ValueType.hpp"
, 339, "assert(" "dimension > 0" ") failed", "not a stable array"
); ::breakpoint(); } } while (0)
;
340 _dimension = dimension;
341 }
342
343 jint dimension() const { return _dimension; }
344
345 virtual StableArrayConstant* as_StableArrayConstant() { return this; }
346};
347
348class InstanceType: public ObjectType {
349 public:
350 virtual InstanceType* as_InstanceType() { return this; }
351};
352
353
354class InstanceConstant: public InstanceType {
355 private:
356 ciInstance* _value;
357
358 public:
359 InstanceConstant(ciInstance* value) { _value = value; }
360
361 ciInstance* value() const { return _value; }
362
363 virtual bool is_constant() const { return true; }
364 virtual InstanceConstant* as_InstanceConstant(){ return this; }
365 virtual ciObject* constant_value() const;
366 virtual ciType* exact_type() const;
367};
368
369
370class MetadataType: public ValueType {
371 public:
372 MetadataType(): ValueType(metaDataTag, 1) {}
373 virtual ValueType* base() const { return objectType; }
374 virtual const char tchar() const { return 'a'; }
375 virtual const char* name() const { return "object"; }
376 virtual MetadataType* as_MetadataType() { return this; }
377 bool is_loaded() const;
378 jobject encoding() const;
379 virtual ciMetadata* constant_value() const { ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_ValueType.hpp"
, 379); ::breakpoint(); } while (0)
; return NULL__null; }
380};
381
382
383class ClassType: public MetadataType {
384 public:
385 virtual ClassType* as_ClassType() { return this; }
386};
387
388
389class ClassConstant: public ClassType {
390 private:
391 ciInstanceKlass* _value;
392
393 public:
394 ClassConstant(ciInstanceKlass* value) { _value = value; }
395
396 ciInstanceKlass* value() const { return _value; }
397
398 virtual bool is_constant() const { return true; }
399 virtual ClassConstant* as_ClassConstant() { return this; }
400 virtual ciMetadata* constant_value() const { return _value; }
401 virtual ciType* exact_type() const;
402};
403
404
405class MethodType: public MetadataType {
406 public:
407 virtual MethodType* as_MethodType() { return this; }
408};
409
410
411class MethodConstant: public MethodType {
412 private:
413 ciMethod* _value;
414
415 public:
416 MethodConstant(ciMethod* value) { _value = value; }
417
418 ciMethod* value() const { return _value; }
419
420 virtual bool is_constant() const { return true; }
421
422 virtual MethodConstant* as_MethodConstant() { return this; }
423 virtual ciMetadata* constant_value() const { return _value; }
424};
425
426
427class AddressType: public ValueType {
428 public:
429 AddressType(): ValueType(addressTag, 1) {}
430 virtual ValueType* base() const { return addressType; }
431 virtual const char tchar() const { return 'r'; }
432 virtual const char* name() const { return "address"; }
433 virtual AddressType* as_AddressType() { return this; }
434};
435
436
437class AddressConstant: public AddressType {
438 private:
439 jint _value;
440
441 public:
442 AddressConstant(jint value) { _value = value; }
443
444 jint value() const { return _value; }
445
446 virtual bool is_constant() const { return true; }
447
448 virtual AddressConstant* as_AddressConstant() { return this; }
449};
450
451
452class IllegalType: public ValueType {
453 public:
454 IllegalType(): ValueType(illegalTag, -1) {}
455 virtual ValueType* base() const { return illegalType; }
456 virtual const char tchar() const { return ' '; }
457 virtual const char* name() const { return "illegal"; }
458 virtual IllegalType* as_IllegalType() { return this; }
459};
460
461
462// conversion between ValueTypes, BasicTypes, and ciConstants
463ValueType* as_ValueType(BasicType type);
464ValueType* as_ValueType(ciConstant value);
465BasicType as_BasicType(ValueType* type);
466
467inline ValueType* as_ValueType(ciType* type) { return as_ValueType(type->basic_type()); }
468
469#endif // SHARE_C1_C1_VALUETYPE_HPP