Bug Summary

File:jdk/src/hotspot/share/ci/ciTypeFlow.cpp
Warning:line 2356, column 11
Although the value stored to 'code' is used in the enclosing expression, the value is never actually read from 'code'

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 ciTypeFlow.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/ci/ciTypeFlow.cpp
1/*
2 * Copyright (c) 2000, 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/ciConstant.hpp"
27#include "ci/ciField.hpp"
28#include "ci/ciMethod.hpp"
29#include "ci/ciMethodData.hpp"
30#include "ci/ciObjArrayKlass.hpp"
31#include "ci/ciStreams.hpp"
32#include "ci/ciTypeArrayKlass.hpp"
33#include "ci/ciTypeFlow.hpp"
34#include "compiler/compileLog.hpp"
35#include "interpreter/bytecode.hpp"
36#include "interpreter/bytecodes.hpp"
37#include "memory/allocation.inline.hpp"
38#include "memory/resourceArea.hpp"
39#include "oops/oop.inline.hpp"
40#include "opto/compile.hpp"
41#include "opto/node.hpp"
42#include "runtime/deoptimization.hpp"
43#include "utilities/growableArray.hpp"
44
45// ciTypeFlow::JsrSet
46//
47// A JsrSet represents some set of JsrRecords. This class
48// is used to record a set of all jsr routines which we permit
49// execution to return (ret) from.
50//
51// During abstract interpretation, JsrSets are used to determine
52// whether two paths which reach a given block are unique, and
53// should be cloned apart, or are compatible, and should merge
54// together.
55
56// ------------------------------------------------------------------
57// ciTypeFlow::JsrSet::JsrSet
58
59// Allocate growable array storage in Arena.
60ciTypeFlow::JsrSet::JsrSet(Arena* arena, int default_len) : _set(arena, default_len, 0, NULL__null) {
61 assert(arena != NULL, "invariant")do { if (!(arena != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 61, "assert(" "arena != __null" ") failed", "invariant"); ::
breakpoint(); } } while (0)
;
62}
63
64// Allocate growable array storage in current ResourceArea.
65ciTypeFlow::JsrSet::JsrSet(int default_len) : _set(default_len, 0, NULL__null) {}
66
67// ------------------------------------------------------------------
68// ciTypeFlow::JsrSet::copy_into
69void ciTypeFlow::JsrSet::copy_into(JsrSet* jsrs) {
70 int len = size();
71 jsrs->_set.clear();
72 for (int i = 0; i < len; i++) {
73 jsrs->_set.append(_set.at(i));
74 }
75}
76
77// ------------------------------------------------------------------
78// ciTypeFlow::JsrSet::is_compatible_with
79//
80// !!!! MISGIVINGS ABOUT THIS... disregard
81//
82// Is this JsrSet compatible with some other JsrSet?
83//
84// In set-theoretic terms, a JsrSet can be viewed as a partial function
85// from entry addresses to return addresses. Two JsrSets A and B are
86// compatible iff
87//
88// For any x,
89// A(x) defined and B(x) defined implies A(x) == B(x)
90//
91// Less formally, two JsrSets are compatible when they have identical
92// return addresses for any entry addresses they share in common.
93bool ciTypeFlow::JsrSet::is_compatible_with(JsrSet* other) {
94 // Walk through both sets in parallel. If the same entry address
95 // appears in both sets, then the return address must match for
96 // the sets to be compatible.
97 int size1 = size();
98 int size2 = other->size();
99
100 // Special case. If nothing is on the jsr stack, then there can
101 // be no ret.
102 if (size2 == 0) {
103 return true;
104 } else if (size1 != size2) {
105 return false;
106 } else {
107 for (int i = 0; i < size1; i++) {
108 JsrRecord* record1 = record_at(i);
109 JsrRecord* record2 = other->record_at(i);
110 if (record1->entry_address() != record2->entry_address() ||
111 record1->return_address() != record2->return_address()) {
112 return false;
113 }
114 }
115 return true;
116 }
117
118#if 0
119 int pos1 = 0;
120 int pos2 = 0;
121 int size1 = size();
122 int size2 = other->size();
123 while (pos1 < size1 && pos2 < size2) {
124 JsrRecord* record1 = record_at(pos1);
125 JsrRecord* record2 = other->record_at(pos2);
126 int entry1 = record1->entry_address();
127 int entry2 = record2->entry_address();
128 if (entry1 < entry2) {
129 pos1++;
130 } else if (entry1 > entry2) {
131 pos2++;
132 } else {
133 if (record1->return_address() == record2->return_address()) {
134 pos1++;
135 pos2++;
136 } else {
137 // These two JsrSets are incompatible.
138 return false;
139 }
140 }
141 }
142 // The two JsrSets agree.
143 return true;
144#endif
145}
146
147// ------------------------------------------------------------------
148// ciTypeFlow::JsrSet::insert_jsr_record
149//
150// Insert the given JsrRecord into the JsrSet, maintaining the order
151// of the set and replacing any element with the same entry address.
152void ciTypeFlow::JsrSet::insert_jsr_record(JsrRecord* record) {
153 int len = size();
154 int entry = record->entry_address();
155 int pos = 0;
156 for ( ; pos < len; pos++) {
157 JsrRecord* current = record_at(pos);
158 if (entry == current->entry_address()) {
159 // Stomp over this entry.
160 _set.at_put(pos, record);
161 assert(size() == len, "must be same size")do { if (!(size() == len)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 161, "assert(" "size() == len" ") failed", "must be same size"
); ::breakpoint(); } } while (0)
;
162 return;
163 } else if (entry < current->entry_address()) {
164 break;
165 }
166 }
167
168 // Insert the record into the list.
169 JsrRecord* swap = record;
170 JsrRecord* temp = NULL__null;
171 for ( ; pos < len; pos++) {
172 temp = _set.at(pos);
173 _set.at_put(pos, swap);
174 swap = temp;
175 }
176 _set.append(swap);
177 assert(size() == len+1, "must be larger")do { if (!(size() == len+1)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 177, "assert(" "size() == len+1" ") failed", "must be larger"
); ::breakpoint(); } } while (0)
;
178}
179
180// ------------------------------------------------------------------
181// ciTypeFlow::JsrSet::remove_jsr_record
182//
183// Remove the JsrRecord with the given return address from the JsrSet.
184void ciTypeFlow::JsrSet::remove_jsr_record(int return_address) {
185 int len = size();
186 for (int i = 0; i < len; i++) {
187 if (record_at(i)->return_address() == return_address) {
188 // We have found the proper entry. Remove it from the
189 // JsrSet and exit.
190 for (int j = i + 1; j < len ; j++) {
191 _set.at_put(j - 1, _set.at(j));
192 }
193 _set.trunc_to(len - 1);
194 assert(size() == len-1, "must be smaller")do { if (!(size() == len-1)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 194, "assert(" "size() == len-1" ") failed", "must be smaller"
); ::breakpoint(); } } while (0)
;
195 return;
196 }
197 }
198 assert(false, "verify: returning from invalid subroutine")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 198, "assert(" "false" ") failed", "verify: returning from invalid subroutine"
); ::breakpoint(); } } while (0)
;
199}
200
201// ------------------------------------------------------------------
202// ciTypeFlow::JsrSet::apply_control
203//
204// Apply the effect of a control-flow bytecode on the JsrSet. The
205// only bytecodes that modify the JsrSet are jsr and ret.
206void ciTypeFlow::JsrSet::apply_control(ciTypeFlow* analyzer,
207 ciBytecodeStream* str,
208 ciTypeFlow::StateVector* state) {
209 Bytecodes::Code code = str->cur_bc();
210 if (code == Bytecodes::_jsr) {
211 JsrRecord* record =
212 analyzer->make_jsr_record(str->get_dest(), str->next_bci());
213 insert_jsr_record(record);
214 } else if (code == Bytecodes::_jsr_w) {
215 JsrRecord* record =
216 analyzer->make_jsr_record(str->get_far_dest(), str->next_bci());
217 insert_jsr_record(record);
218 } else if (code == Bytecodes::_ret) {
219 Cell local = state->local(str->get_index());
220 ciType* return_address = state->type_at(local);
221 assert(return_address->is_return_address(), "verify: wrong type")do { if (!(return_address->is_return_address())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 221, "assert(" "return_address->is_return_address()" ") failed"
, "verify: wrong type"); ::breakpoint(); } } while (0)
;
222 if (size() == 0) {
223 // Ret-state underflow: Hit a ret w/o any previous jsrs. Bail out.
224 // This can happen when a loop is inside a finally clause (4614060).
225 analyzer->record_failure("OSR in finally clause");
226 return;
227 }
228 remove_jsr_record(return_address->as_return_address()->bci());
229 }
230}
231
232#ifndef PRODUCT
233// ------------------------------------------------------------------
234// ciTypeFlow::JsrSet::print_on
235void ciTypeFlow::JsrSet::print_on(outputStream* st) const {
236 st->print("{ ");
237 int num_elements = size();
238 if (num_elements > 0) {
239 int i = 0;
240 for( ; i < num_elements - 1; i++) {
241 _set.at(i)->print_on(st);
242 st->print(", ");
243 }
244 _set.at(i)->print_on(st);
245 st->print(" ");
246 }
247 st->print("}");
248}
249#endif
250
251// ciTypeFlow::StateVector
252//
253// A StateVector summarizes the type information at some point in
254// the program.
255
256// ------------------------------------------------------------------
257// ciTypeFlow::StateVector::type_meet
258//
259// Meet two types.
260//
261// The semi-lattice of types use by this analysis are modeled on those
262// of the verifier. The lattice is as follows:
263//
264// top_type() >= all non-extremal types >= bottom_type
265// and
266// Every primitive type is comparable only with itself. The meet of
267// reference types is determined by their kind: instance class,
268// interface, or array class. The meet of two types of the same
269// kind is their least common ancestor. The meet of two types of
270// different kinds is always java.lang.Object.
271ciType* ciTypeFlow::StateVector::type_meet_internal(ciType* t1, ciType* t2, ciTypeFlow* analyzer) {
272 assert(t1 != t2, "checked in caller")do { if (!(t1 != t2)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 272, "assert(" "t1 != t2" ") failed", "checked in caller");
::breakpoint(); } } while (0)
;
273 if (t1->equals(top_type())) {
274 return t2;
275 } else if (t2->equals(top_type())) {
276 return t1;
277 } else if (t1->is_primitive_type() || t2->is_primitive_type()) {
278 // Special case null_type. null_type meet any reference type T
279 // is T. null_type meet null_type is null_type.
280 if (t1->equals(null_type())) {
281 if (!t2->is_primitive_type() || t2->equals(null_type())) {
282 return t2;
283 }
284 } else if (t2->equals(null_type())) {
285 if (!t1->is_primitive_type()) {
286 return t1;
287 }
288 }
289
290 // At least one of the two types is a non-top primitive type.
291 // The other type is not equal to it. Fall to bottom.
292 return bottom_type();
293 } else {
294 // Both types are non-top non-primitive types. That is,
295 // both types are either instanceKlasses or arrayKlasses.
296 ciKlass* object_klass = analyzer->env()->Object_klass();
297 ciKlass* k1 = t1->as_klass();
298 ciKlass* k2 = t2->as_klass();
299 if (k1->equals(object_klass) || k2->equals(object_klass)) {
300 return object_klass;
301 } else if (!k1->is_loaded() || !k2->is_loaded()) {
302 // Unloaded classes fall to java.lang.Object at a merge.
303 return object_klass;
304 } else if (k1->is_interface() != k2->is_interface()) {
305 // When an interface meets a non-interface, we get Object;
306 // This is what the verifier does.
307 return object_klass;
308 } else if (k1->is_array_klass() || k2->is_array_klass()) {
309 // When an array meets a non-array, we get Object.
310 // When objArray meets typeArray, we also get Object.
311 // And when typeArray meets different typeArray, we again get Object.
312 // But when objArray meets objArray, we look carefully at element types.
313 if (k1->is_obj_array_klass() && k2->is_obj_array_klass()) {
314 // Meet the element types, then construct the corresponding array type.
315 ciKlass* elem1 = k1->as_obj_array_klass()->element_klass();
316 ciKlass* elem2 = k2->as_obj_array_klass()->element_klass();
317 ciKlass* elem = type_meet_internal(elem1, elem2, analyzer)->as_klass();
318 // Do an easy shortcut if one type is a super of the other.
319 if (elem == elem1) {
320 assert(k1 == ciObjArrayKlass::make(elem), "shortcut is OK")do { if (!(k1 == ciObjArrayKlass::make(elem))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 320, "assert(" "k1 == ciObjArrayKlass::make(elem)" ") failed"
, "shortcut is OK"); ::breakpoint(); } } while (0)
;
321 return k1;
322 } else if (elem == elem2) {
323 assert(k2 == ciObjArrayKlass::make(elem), "shortcut is OK")do { if (!(k2 == ciObjArrayKlass::make(elem))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 323, "assert(" "k2 == ciObjArrayKlass::make(elem)" ") failed"
, "shortcut is OK"); ::breakpoint(); } } while (0)
;
324 return k2;
325 } else {
326 return ciObjArrayKlass::make(elem);
327 }
328 } else {
329 return object_klass;
330 }
331 } else {
332 // Must be two plain old instance klasses.
333 assert(k1->is_instance_klass(), "previous cases handle non-instances")do { if (!(k1->is_instance_klass())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 333, "assert(" "k1->is_instance_klass()" ") failed", "previous cases handle non-instances"
); ::breakpoint(); } } while (0)
;
334 assert(k2->is_instance_klass(), "previous cases handle non-instances")do { if (!(k2->is_instance_klass())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 334, "assert(" "k2->is_instance_klass()" ") failed", "previous cases handle non-instances"
); ::breakpoint(); } } while (0)
;
335 return k1->least_common_ancestor(k2);
336 }
337 }
338}
339
340
341// ------------------------------------------------------------------
342// ciTypeFlow::StateVector::StateVector
343//
344// Build a new state vector
345ciTypeFlow::StateVector::StateVector(ciTypeFlow* analyzer) {
346 _outer = analyzer;
347 _stack_size = -1;
348 _monitor_count = -1;
349 // Allocate the _types array
350 int max_cells = analyzer->max_cells();
351 _types = (ciType**)analyzer->arena()->Amalloc(sizeof(ciType*) * max_cells);
352 for (int i=0; i<max_cells; i++) {
353 _types[i] = top_type();
354 }
355 _trap_bci = -1;
356 _trap_index = 0;
357 _def_locals.clear();
358}
359
360
361// ------------------------------------------------------------------
362// ciTypeFlow::get_start_state
363//
364// Set this vector to the method entry state.
365const ciTypeFlow::StateVector* ciTypeFlow::get_start_state() {
366 StateVector* state = new StateVector(this);
367 if (is_osr_flow()) {
368 ciTypeFlow* non_osr_flow = method()->get_flow_analysis();
369 if (non_osr_flow->failing()) {
370 record_failure(non_osr_flow->failure_reason());
371 return NULL__null;
372 }
373 JsrSet* jsrs = new JsrSet(4);
374 Block* non_osr_block = non_osr_flow->existing_block_at(start_bci(), jsrs);
375 if (non_osr_block == NULL__null) {
376 record_failure("cannot reach OSR point");
377 return NULL__null;
378 }
379 // load up the non-OSR state at this point
380 non_osr_block->copy_state_into(state);
381 int non_osr_start = non_osr_block->start();
382 if (non_osr_start != start_bci()) {
383 // must flow forward from it
384 if (CITraceTypeFlow) {
385 tty->print_cr(">> Interpreting pre-OSR block %d:", non_osr_start);
386 }
387 Block* block = block_at(non_osr_start, jsrs);
388 assert(block->limit() == start_bci(), "must flow forward to start")do { if (!(block->limit() == start_bci())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 388, "assert(" "block->limit() == start_bci()" ") failed"
, "must flow forward to start"); ::breakpoint(); } } while (0
)
;
389 flow_block(block, state, jsrs);
390 }
391 return state;
392 // Note: The code below would be an incorrect for an OSR flow,
393 // even if it were possible for an OSR entry point to be at bci zero.
394 }
395 // "Push" the method signature into the first few locals.
396 state->set_stack_size(-max_locals());
397 if (!method()->is_static()) {
398 state->push(method()->holder());
399 assert(state->tos() == state->local(0), "")do { if (!(state->tos() == state->local(0))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 399, "assert(" "state->tos() == state->local(0)" ") failed"
, ""); ::breakpoint(); } } while (0)
;
400 }
401 for (ciSignatureStream str(method()->signature());
402 !str.at_return_type();
403 str.next()) {
404 state->push_translate(str.type());
405 }
406 // Set the rest of the locals to bottom.
407 Cell cell = state->next_cell(state->tos());
408 state->set_stack_size(0);
409 int limit = state->limit_cell();
410 for (; cell < limit; cell = state->next_cell(cell)) {
411 state->set_type_at(cell, state->bottom_type());
412 }
413 // Lock an object, if necessary.
414 state->set_monitor_count(method()->is_synchronized() ? 1 : 0);
415 return state;
416}
417
418// ------------------------------------------------------------------
419// ciTypeFlow::StateVector::copy_into
420//
421// Copy our value into some other StateVector
422void ciTypeFlow::StateVector::copy_into(ciTypeFlow::StateVector* copy)
423const {
424 copy->set_stack_size(stack_size());
425 copy->set_monitor_count(monitor_count());
426 Cell limit = limit_cell();
427 for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
428 copy->set_type_at(c, type_at(c));
429 }
430}
431
432// ------------------------------------------------------------------
433// ciTypeFlow::StateVector::meet
434//
435// Meets this StateVector with another, destructively modifying this
436// one. Returns true if any modification takes place.
437bool ciTypeFlow::StateVector::meet(const ciTypeFlow::StateVector* incoming) {
438 if (monitor_count() == -1) {
439 set_monitor_count(incoming->monitor_count());
440 }
441 assert(monitor_count() == incoming->monitor_count(), "monitors must match")do { if (!(monitor_count() == incoming->monitor_count())) {
(*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 441, "assert(" "monitor_count() == incoming->monitor_count()"
") failed", "monitors must match"); ::breakpoint(); } } while
(0)
;
442
443 if (stack_size() == -1) {
444 set_stack_size(incoming->stack_size());
445 Cell limit = limit_cell();
446 #ifdef ASSERT1
447 { for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
448 assert(type_at(c) == top_type(), "")do { if (!(type_at(c) == top_type())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 448, "assert(" "type_at(c) == top_type()" ") failed", ""); ::
breakpoint(); } } while (0)
;
449 } }
450 #endif
451 // Make a simple copy of the incoming state.
452 for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
453 set_type_at(c, incoming->type_at(c));
454 }
455 return true; // it is always different the first time
456 }
457#ifdef ASSERT1
458 if (stack_size() != incoming->stack_size()) {
459 _outer->method()->print_codes();
460 tty->print_cr("!!!! Stack size conflict");
461 tty->print_cr("Current state:");
462 print_on(tty);
463 tty->print_cr("Incoming state:");
464 ((StateVector*)incoming)->print_on(tty);
465 }
466#endif
467 assert(stack_size() == incoming->stack_size(), "sanity")do { if (!(stack_size() == incoming->stack_size())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 467, "assert(" "stack_size() == incoming->stack_size()" ") failed"
, "sanity"); ::breakpoint(); } } while (0)
;
468
469 bool different = false;
470 Cell limit = limit_cell();
471 for (Cell c = start_cell(); c < limit; c = next_cell(c)) {
472 ciType* t1 = type_at(c);
473 ciType* t2 = incoming->type_at(c);
474 if (!t1->equals(t2)) {
475 ciType* new_type = type_meet(t1, t2);
476 if (!t1->equals(new_type)) {
477 set_type_at(c, new_type);
478 different = true;
479 }
480 }
481 }
482 return different;
483}
484
485// ------------------------------------------------------------------
486// ciTypeFlow::StateVector::meet_exception
487//
488// Meets this StateVector with another, destructively modifying this
489// one. The incoming state is coming via an exception. Returns true
490// if any modification takes place.
491bool ciTypeFlow::StateVector::meet_exception(ciInstanceKlass* exc,
492 const ciTypeFlow::StateVector* incoming) {
493 if (monitor_count() == -1) {
494 set_monitor_count(incoming->monitor_count());
495 }
496 assert(monitor_count() == incoming->monitor_count(), "monitors must match")do { if (!(monitor_count() == incoming->monitor_count())) {
(*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 496, "assert(" "monitor_count() == incoming->monitor_count()"
") failed", "monitors must match"); ::breakpoint(); } } while
(0)
;
497
498 if (stack_size() == -1) {
499 set_stack_size(1);
500 }
501
502 assert(stack_size() == 1, "must have one-element stack")do { if (!(stack_size() == 1)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 502, "assert(" "stack_size() == 1" ") failed", "must have one-element stack"
); ::breakpoint(); } } while (0)
;
503
504 bool different = false;
505
506 // Meet locals from incoming array.
507 Cell limit = local(_outer->max_locals()-1);
508 for (Cell c = start_cell(); c <= limit; c = next_cell(c)) {
509 ciType* t1 = type_at(c);
510 ciType* t2 = incoming->type_at(c);
511 if (!t1->equals(t2)) {
512 ciType* new_type = type_meet(t1, t2);
513 if (!t1->equals(new_type)) {
514 set_type_at(c, new_type);
515 different = true;
516 }
517 }
518 }
519
520 // Handle stack separately. When an exception occurs, the
521 // only stack entry is the exception instance.
522 ciType* tos_type = type_at_tos();
523 if (!tos_type->equals(exc)) {
524 ciType* new_type = type_meet(tos_type, exc);
525 if (!tos_type->equals(new_type)) {
526 set_type_at_tos(new_type);
527 different = true;
528 }
529 }
530
531 return different;
532}
533
534// ------------------------------------------------------------------
535// ciTypeFlow::StateVector::push_translate
536void ciTypeFlow::StateVector::push_translate(ciType* type) {
537 BasicType basic_type = type->basic_type();
538 if (basic_type == T_BOOLEAN || basic_type == T_CHAR ||
539 basic_type == T_BYTE || basic_type == T_SHORT) {
540 push_int();
541 } else {
542 push(type);
543 if (type->is_two_word()) {
544 push(half_type(type));
545 }
546 }
547}
548
549// ------------------------------------------------------------------
550// ciTypeFlow::StateVector::do_aaload
551void ciTypeFlow::StateVector::do_aaload(ciBytecodeStream* str) {
552 pop_int();
553 ciObjArrayKlass* array_klass = pop_objArray();
554 if (array_klass == NULL__null) {
555 // Did aaload on a null reference; push a null and ignore the exception.
556 // This instruction will never continue normally. All we have to do
557 // is report a value that will meet correctly with any downstream
558 // reference types on paths that will truly be executed. This null type
559 // meets with any reference type to yield that same reference type.
560 // (The compiler will generate an unconditional exception here.)
561 push(null_type());
562 return;
563 }
564 if (!array_klass->is_loaded()) {
565 // Only fails for some -Xcomp runs
566 trap(str, array_klass,
567 Deoptimization::make_trap_request
568 (Deoptimization::Reason_unloaded,
569 Deoptimization::Action_reinterpret));
570 return;
571 }
572 ciKlass* element_klass = array_klass->element_klass();
573 if (!element_klass->is_loaded() && element_klass->is_instance_klass()) {
574 Untested("unloaded array element class in ciTypeFlow")do { report_untested("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 574, "unloaded array element class in ciTypeFlow"); ::breakpoint
(); } while (0);
;
575 trap(str, element_klass,
576 Deoptimization::make_trap_request
577 (Deoptimization::Reason_unloaded,
578 Deoptimization::Action_reinterpret));
579 } else {
580 push_object(element_klass);
581 }
582}
583
584
585// ------------------------------------------------------------------
586// ciTypeFlow::StateVector::do_checkcast
587void ciTypeFlow::StateVector::do_checkcast(ciBytecodeStream* str) {
588 bool will_link;
589 ciKlass* klass = str->get_klass(will_link);
590 if (!will_link) {
591 // VM's interpreter will not load 'klass' if object is NULL.
592 // Type flow after this block may still be needed in two situations:
593 // 1) C2 uses do_null_assert() and continues compilation for later blocks
594 // 2) C2 does an OSR compile in a later block (see bug 4778368).
595 pop_object();
596 do_null_assert(klass);
597 } else {
598 pop_object();
599 push_object(klass);
600 }
601}
602
603// ------------------------------------------------------------------
604// ciTypeFlow::StateVector::do_getfield
605void ciTypeFlow::StateVector::do_getfield(ciBytecodeStream* str) {
606 // could add assert here for type of object.
607 pop_object();
608 do_getstatic(str);
609}
610
611// ------------------------------------------------------------------
612// ciTypeFlow::StateVector::do_getstatic
613void ciTypeFlow::StateVector::do_getstatic(ciBytecodeStream* str) {
614 bool will_link;
615 ciField* field = str->get_field(will_link);
616 if (!will_link) {
617 trap(str, field->holder(), str->get_field_holder_index());
618 } else {
619 ciType* field_type = field->type();
620 if (!field_type->is_loaded()) {
621 // Normally, we need the field's type to be loaded if we are to
622 // do anything interesting with its value.
623 // We used to do this: trap(str, str->get_field_signature_index());
624 //
625 // There is one good reason not to trap here. Execution can
626 // get past this "getfield" or "getstatic" if the value of
627 // the field is null. As long as the value is null, the class
628 // does not need to be loaded! The compiler must assume that
629 // the value of the unloaded class reference is null; if the code
630 // ever sees a non-null value, loading has occurred.
631 //
632 // This actually happens often enough to be annoying. If the
633 // compiler throws an uncommon trap at this bytecode, you can
634 // get an endless loop of recompilations, when all the code
635 // needs to do is load a series of null values. Also, a trap
636 // here can make an OSR entry point unreachable, triggering the
637 // assert on non_osr_block in ciTypeFlow::get_start_state.
638 // (See bug 4379915.)
639 do_null_assert(field_type->as_klass());
640 } else {
641 push_translate(field_type);
642 }
643 }
644}
645
646// ------------------------------------------------------------------
647// ciTypeFlow::StateVector::do_invoke
648void ciTypeFlow::StateVector::do_invoke(ciBytecodeStream* str,
649 bool has_receiver) {
650 bool will_link;
651 ciSignature* declared_signature = NULL__null;
652 ciMethod* callee = str->get_method(will_link, &declared_signature);
653 assert(declared_signature != NULL, "cannot be null")do { if (!(declared_signature != __null)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 653, "assert(" "declared_signature != __null" ") failed", "cannot be null"
); ::breakpoint(); } } while (0)
;
654 if (!will_link) {
655 // We weren't able to find the method.
656 if (str->cur_bc() == Bytecodes::_invokedynamic) {
657 trap(str, NULL__null,
658 Deoptimization::make_trap_request
659 (Deoptimization::Reason_uninitialized,
660 Deoptimization::Action_reinterpret));
661 } else {
662 ciKlass* unloaded_holder = callee->holder();
663 trap(str, unloaded_holder, str->get_method_holder_index());
664 }
665 } else {
666 // We are using the declared signature here because it might be
667 // different from the callee signature (Cf. invokedynamic and
668 // invokehandle).
669 ciSignatureStream sigstr(declared_signature);
670 const int arg_size = declared_signature->size();
671 const int stack_base = stack_size() - arg_size;
672 int i = 0;
673 for( ; !sigstr.at_return_type(); sigstr.next()) {
674 ciType* type = sigstr.type();
675 ciType* stack_type = type_at(stack(stack_base + i++));
676 // Do I want to check this type?
677 // assert(stack_type->is_subtype_of(type), "bad type for field value");
678 if (type->is_two_word()) {
679 ciType* stack_type2 = type_at(stack(stack_base + i++));
680 assert(stack_type2->equals(half_type(type)), "must be 2nd half")do { if (!(stack_type2->equals(half_type(type)))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 680, "assert(" "stack_type2->equals(half_type(type))" ") failed"
, "must be 2nd half"); ::breakpoint(); } } while (0)
;
681 }
682 }
683 assert(arg_size == i, "must match")do { if (!(arg_size == i)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 683, "assert(" "arg_size == i" ") failed", "must match"); ::
breakpoint(); } } while (0)
;
684 for (int j = 0; j < arg_size; j++) {
685 pop();
686 }
687 if (has_receiver) {
688 // Check this?
689 pop_object();
690 }
691 assert(!sigstr.is_done(), "must have return type")do { if (!(!sigstr.is_done())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 691, "assert(" "!sigstr.is_done()" ") failed", "must have return type"
); ::breakpoint(); } } while (0)
;
692 ciType* return_type = sigstr.type();
693 if (!return_type->is_void()) {
694 if (!return_type->is_loaded()) {
695 // As in do_getstatic(), generally speaking, we need the return type to
696 // be loaded if we are to do anything interesting with its value.
697 // We used to do this: trap(str, str->get_method_signature_index());
698 //
699 // We do not trap here since execution can get past this invoke if
700 // the return value is null. As long as the value is null, the class
701 // does not need to be loaded! The compiler must assume that
702 // the value of the unloaded class reference is null; if the code
703 // ever sees a non-null value, loading has occurred.
704 //
705 // See do_getstatic() for similar explanation, as well as bug 4684993.
706 do_null_assert(return_type->as_klass());
707 } else {
708 push_translate(return_type);
709 }
710 }
711 }
712}
713
714// ------------------------------------------------------------------
715// ciTypeFlow::StateVector::do_jsr
716void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) {
717 push(ciReturnAddress::make(str->next_bci()));
718}
719
720// ------------------------------------------------------------------
721// ciTypeFlow::StateVector::do_ldc
722void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) {
723 ciConstant con = str->get_constant();
724 if (con.is_valid()) {
725 BasicType basic_type = con.basic_type();
726 if (is_reference_type(basic_type)) {
727 ciObject* obj = con.as_object();
728 if (obj->is_null_object()) {
729 push_null();
730 } else {
731 assert(obj->is_instance() || obj->is_array(), "must be java_mirror of klass")do { if (!(obj->is_instance() || obj->is_array())) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 731, "assert(" "obj->is_instance() || obj->is_array()"
") failed", "must be java_mirror of klass"); ::breakpoint();
} } while (0)
;
732 push_object(obj->klass());
733 }
734 } else {
735 push_translate(ciType::make(basic_type));
736 }
737 } else {
738 if (str->is_unresolved_klass_in_error()) {
739 trap(str, NULL__null, Deoptimization::make_trap_request(Deoptimization::Reason_unhandled,
740 Deoptimization::Action_none));
741 } else {
742 // OutOfMemoryError in the CI while loading constant
743 push_null();
744 outer()->record_failure("ldc did not link");
745 }
746 }
747}
748
749// ------------------------------------------------------------------
750// ciTypeFlow::StateVector::do_multianewarray
751void ciTypeFlow::StateVector::do_multianewarray(ciBytecodeStream* str) {
752 int dimensions = str->get_dimensions();
753 bool will_link;
754 ciArrayKlass* array_klass = str->get_klass(will_link)->as_array_klass();
755 if (!will_link) {
756 trap(str, array_klass, str->get_klass_index());
757 } else {
758 for (int i = 0; i < dimensions; i++) {
759 pop_int();
760 }
761 push_object(array_klass);
762 }
763}
764
765// ------------------------------------------------------------------
766// ciTypeFlow::StateVector::do_new
767void ciTypeFlow::StateVector::do_new(ciBytecodeStream* str) {
768 bool will_link;
769 ciKlass* klass = str->get_klass(will_link);
770 if (!will_link || str->is_unresolved_klass()) {
771 trap(str, klass, str->get_klass_index());
772 } else {
773 push_object(klass);
774 }
775}
776
777// ------------------------------------------------------------------
778// ciTypeFlow::StateVector::do_newarray
779void ciTypeFlow::StateVector::do_newarray(ciBytecodeStream* str) {
780 pop_int();
781 ciKlass* klass = ciTypeArrayKlass::make((BasicType)str->get_index());
782 push_object(klass);
783}
784
785// ------------------------------------------------------------------
786// ciTypeFlow::StateVector::do_putfield
787void ciTypeFlow::StateVector::do_putfield(ciBytecodeStream* str) {
788 do_putstatic(str);
789 if (_trap_bci != -1) return; // unloaded field holder, etc.
790 // could add assert here for type of object.
791 pop_object();
792}
793
794// ------------------------------------------------------------------
795// ciTypeFlow::StateVector::do_putstatic
796void ciTypeFlow::StateVector::do_putstatic(ciBytecodeStream* str) {
797 bool will_link;
798 ciField* field = str->get_field(will_link);
799 if (!will_link) {
800 trap(str, field->holder(), str->get_field_holder_index());
801 } else {
802 ciType* field_type = field->type();
803 ciType* type = pop_value();
804 // Do I want to check this type?
805 // assert(type->is_subtype_of(field_type), "bad type for field value");
806 if (field_type->is_two_word()) {
807 ciType* type2 = pop_value();
808 assert(type2->is_two_word(), "must be 2nd half")do { if (!(type2->is_two_word())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 808, "assert(" "type2->is_two_word()" ") failed", "must be 2nd half"
); ::breakpoint(); } } while (0)
;
809 assert(type == half_type(type2), "must be 2nd half")do { if (!(type == half_type(type2))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 809, "assert(" "type == half_type(type2)" ") failed", "must be 2nd half"
); ::breakpoint(); } } while (0)
;
810 }
811 }
812}
813
814// ------------------------------------------------------------------
815// ciTypeFlow::StateVector::do_ret
816void ciTypeFlow::StateVector::do_ret(ciBytecodeStream* str) {
817 Cell index = local(str->get_index());
818
819 ciType* address = type_at(index);
820 assert(address->is_return_address(), "bad return address")do { if (!(address->is_return_address())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 820, "assert(" "address->is_return_address()" ") failed"
, "bad return address"); ::breakpoint(); } } while (0)
;
821 set_type_at(index, bottom_type());
822}
823
824// ------------------------------------------------------------------
825// ciTypeFlow::StateVector::trap
826//
827// Stop interpretation of this path with a trap.
828void ciTypeFlow::StateVector::trap(ciBytecodeStream* str, ciKlass* klass, int index) {
829 _trap_bci = str->cur_bci();
830 _trap_index = index;
831
832 // Log information about this trap:
833 CompileLog* log = outer()->env()->log();
834 if (log != NULL__null) {
835 int mid = log->identify(outer()->method());
836 int kid = (klass == NULL__null)? -1: log->identify(klass);
837 log->begin_elem("uncommon_trap method='%d' bci='%d'", mid, str->cur_bci());
838 char buf[100];
839 log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf),
840 index));
841 if (kid >= 0)
842 log->print(" klass='%d'", kid);
843 log->end_elem();
844 }
845}
846
847// ------------------------------------------------------------------
848// ciTypeFlow::StateVector::do_null_assert
849// Corresponds to graphKit::do_null_assert.
850void ciTypeFlow::StateVector::do_null_assert(ciKlass* unloaded_klass) {
851 if (unloaded_klass->is_loaded()) {
852 // We failed to link, but we can still compute with this class,
853 // since it is loaded somewhere. The compiler will uncommon_trap
854 // if the object is not null, but the typeflow pass can not assume
855 // that the object will be null, otherwise it may incorrectly tell
856 // the parser that an object is known to be null. 4761344, 4807707
857 push_object(unloaded_klass);
858 } else {
859 // The class is not loaded anywhere. It is safe to model the
860 // null in the typestates, because we can compile in a null check
861 // which will deoptimize us if someone manages to load the
862 // class later.
863 push_null();
864 }
865}
866
867
868// ------------------------------------------------------------------
869// ciTypeFlow::StateVector::apply_one_bytecode
870//
871// Apply the effect of one bytecode to this StateVector
872bool ciTypeFlow::StateVector::apply_one_bytecode(ciBytecodeStream* str) {
873 _trap_bci = -1;
874 _trap_index = 0;
875
876 if (CITraceTypeFlow) {
877 tty->print_cr(">> Interpreting bytecode %d:%s", str->cur_bci(),
878 Bytecodes::name(str->cur_bc()));
879 }
880
881 switch(str->cur_bc()) {
882 case Bytecodes::_aaload: do_aaload(str); break;
883
884 case Bytecodes::_aastore:
885 {
886 pop_object();
887 pop_int();
888 pop_objArray();
889 break;
890 }
891 case Bytecodes::_aconst_null:
892 {
893 push_null();
894 break;
895 }
896 case Bytecodes::_aload: load_local_object(str->get_index()); break;
897 case Bytecodes::_aload_0: load_local_object(0); break;
898 case Bytecodes::_aload_1: load_local_object(1); break;
899 case Bytecodes::_aload_2: load_local_object(2); break;
900 case Bytecodes::_aload_3: load_local_object(3); break;
901
902 case Bytecodes::_anewarray:
903 {
904 pop_int();
905 bool will_link;
906 ciKlass* element_klass = str->get_klass(will_link);
907 if (!will_link) {
908 trap(str, element_klass, str->get_klass_index());
909 } else {
910 push_object(ciObjArrayKlass::make(element_klass));
911 }
912 break;
913 }
914 case Bytecodes::_areturn:
915 case Bytecodes::_ifnonnull:
916 case Bytecodes::_ifnull:
917 {
918 pop_object();
919 break;
920 }
921 case Bytecodes::_monitorenter:
922 {
923 pop_object();
924 set_monitor_count(monitor_count() + 1);
925 break;
926 }
927 case Bytecodes::_monitorexit:
928 {
929 pop_object();
930 assert(monitor_count() > 0, "must be a monitor to exit from")do { if (!(monitor_count() > 0)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 930, "assert(" "monitor_count() > 0" ") failed", "must be a monitor to exit from"
); ::breakpoint(); } } while (0)
;
931 set_monitor_count(monitor_count() - 1);
932 break;
933 }
934 case Bytecodes::_arraylength:
935 {
936 pop_array();
937 push_int();
938 break;
939 }
940 case Bytecodes::_astore: store_local_object(str->get_index()); break;
941 case Bytecodes::_astore_0: store_local_object(0); break;
942 case Bytecodes::_astore_1: store_local_object(1); break;
943 case Bytecodes::_astore_2: store_local_object(2); break;
944 case Bytecodes::_astore_3: store_local_object(3); break;
945
946 case Bytecodes::_athrow:
947 {
948 NEEDS_CLEANUP;
949 pop_object();
950 break;
951 }
952 case Bytecodes::_baload:
953 case Bytecodes::_caload:
954 case Bytecodes::_iaload:
955 case Bytecodes::_saload:
956 {
957 pop_int();
958 ciTypeArrayKlass* array_klass = pop_typeArray();
959 // Put assert here for right type?
960 push_int();
961 break;
962 }
963 case Bytecodes::_bastore:
964 case Bytecodes::_castore:
965 case Bytecodes::_iastore:
966 case Bytecodes::_sastore:
967 {
968 pop_int();
969 pop_int();
970 pop_typeArray();
971 // assert here?
972 break;
973 }
974 case Bytecodes::_bipush:
975 case Bytecodes::_iconst_m1:
976 case Bytecodes::_iconst_0:
977 case Bytecodes::_iconst_1:
978 case Bytecodes::_iconst_2:
979 case Bytecodes::_iconst_3:
980 case Bytecodes::_iconst_4:
981 case Bytecodes::_iconst_5:
982 case Bytecodes::_sipush:
983 {
984 push_int();
985 break;
986 }
987 case Bytecodes::_checkcast: do_checkcast(str); break;
988
989 case Bytecodes::_d2f:
990 {
991 pop_double();
992 push_float();
993 break;
994 }
995 case Bytecodes::_d2i:
996 {
997 pop_double();
998 push_int();
999 break;
1000 }
1001 case Bytecodes::_d2l:
1002 {
1003 pop_double();
1004 push_long();
1005 break;
1006 }
1007 case Bytecodes::_dadd:
1008 case Bytecodes::_ddiv:
1009 case Bytecodes::_dmul:
1010 case Bytecodes::_drem:
1011 case Bytecodes::_dsub:
1012 {
1013 pop_double();
1014 pop_double();
1015 push_double();
1016 break;
1017 }
1018 case Bytecodes::_daload:
1019 {
1020 pop_int();
1021 ciTypeArrayKlass* array_klass = pop_typeArray();
1022 // Put assert here for right type?
1023 push_double();
1024 break;
1025 }
1026 case Bytecodes::_dastore:
1027 {
1028 pop_double();
1029 pop_int();
1030 pop_typeArray();
1031 // assert here?
1032 break;
1033 }
1034 case Bytecodes::_dcmpg:
1035 case Bytecodes::_dcmpl:
1036 {
1037 pop_double();
1038 pop_double();
1039 push_int();
1040 break;
1041 }
1042 case Bytecodes::_dconst_0:
1043 case Bytecodes::_dconst_1:
1044 {
1045 push_double();
1046 break;
1047 }
1048 case Bytecodes::_dload: load_local_double(str->get_index()); break;
1049 case Bytecodes::_dload_0: load_local_double(0); break;
1050 case Bytecodes::_dload_1: load_local_double(1); break;
1051 case Bytecodes::_dload_2: load_local_double(2); break;
1052 case Bytecodes::_dload_3: load_local_double(3); break;
1053
1054 case Bytecodes::_dneg:
1055 {
1056 pop_double();
1057 push_double();
1058 break;
1059 }
1060 case Bytecodes::_dreturn:
1061 {
1062 pop_double();
1063 break;
1064 }
1065 case Bytecodes::_dstore: store_local_double(str->get_index()); break;
1066 case Bytecodes::_dstore_0: store_local_double(0); break;
1067 case Bytecodes::_dstore_1: store_local_double(1); break;
1068 case Bytecodes::_dstore_2: store_local_double(2); break;
1069 case Bytecodes::_dstore_3: store_local_double(3); break;
1070
1071 case Bytecodes::_dup:
1072 {
1073 push(type_at_tos());
1074 break;
1075 }
1076 case Bytecodes::_dup_x1:
1077 {
1078 ciType* value1 = pop_value();
1079 ciType* value2 = pop_value();
1080 push(value1);
1081 push(value2);
1082 push(value1);
1083 break;
1084 }
1085 case Bytecodes::_dup_x2:
1086 {
1087 ciType* value1 = pop_value();
1088 ciType* value2 = pop_value();
1089 ciType* value3 = pop_value();
1090 push(value1);
1091 push(value3);
1092 push(value2);
1093 push(value1);
1094 break;
1095 }
1096 case Bytecodes::_dup2:
1097 {
1098 ciType* value1 = pop_value();
1099 ciType* value2 = pop_value();
1100 push(value2);
1101 push(value1);
1102 push(value2);
1103 push(value1);
1104 break;
1105 }
1106 case Bytecodes::_dup2_x1:
1107 {
1108 ciType* value1 = pop_value();
1109 ciType* value2 = pop_value();
1110 ciType* value3 = pop_value();
1111 push(value2);
1112 push(value1);
1113 push(value3);
1114 push(value2);
1115 push(value1);
1116 break;
1117 }
1118 case Bytecodes::_dup2_x2:
1119 {
1120 ciType* value1 = pop_value();
1121 ciType* value2 = pop_value();
1122 ciType* value3 = pop_value();
1123 ciType* value4 = pop_value();
1124 push(value2);
1125 push(value1);
1126 push(value4);
1127 push(value3);
1128 push(value2);
1129 push(value1);
1130 break;
1131 }
1132 case Bytecodes::_f2d:
1133 {
1134 pop_float();
1135 push_double();
1136 break;
1137 }
1138 case Bytecodes::_f2i:
1139 {
1140 pop_float();
1141 push_int();
1142 break;
1143 }
1144 case Bytecodes::_f2l:
1145 {
1146 pop_float();
1147 push_long();
1148 break;
1149 }
1150 case Bytecodes::_fadd:
1151 case Bytecodes::_fdiv:
1152 case Bytecodes::_fmul:
1153 case Bytecodes::_frem:
1154 case Bytecodes::_fsub:
1155 {
1156 pop_float();
1157 pop_float();
1158 push_float();
1159 break;
1160 }
1161 case Bytecodes::_faload:
1162 {
1163 pop_int();
1164 ciTypeArrayKlass* array_klass = pop_typeArray();
1165 // Put assert here.
1166 push_float();
1167 break;
1168 }
1169 case Bytecodes::_fastore:
1170 {
1171 pop_float();
1172 pop_int();
1173 ciTypeArrayKlass* array_klass = pop_typeArray();
1174 // Put assert here.
1175 break;
1176 }
1177 case Bytecodes::_fcmpg:
1178 case Bytecodes::_fcmpl:
1179 {
1180 pop_float();
1181 pop_float();
1182 push_int();
1183 break;
1184 }
1185 case Bytecodes::_fconst_0:
1186 case Bytecodes::_fconst_1:
1187 case Bytecodes::_fconst_2:
1188 {
1189 push_float();
1190 break;
1191 }
1192 case Bytecodes::_fload: load_local_float(str->get_index()); break;
1193 case Bytecodes::_fload_0: load_local_float(0); break;
1194 case Bytecodes::_fload_1: load_local_float(1); break;
1195 case Bytecodes::_fload_2: load_local_float(2); break;
1196 case Bytecodes::_fload_3: load_local_float(3); break;
1197
1198 case Bytecodes::_fneg:
1199 {
1200 pop_float();
1201 push_float();
1202 break;
1203 }
1204 case Bytecodes::_freturn:
1205 {
1206 pop_float();
1207 break;
1208 }
1209 case Bytecodes::_fstore: store_local_float(str->get_index()); break;
1210 case Bytecodes::_fstore_0: store_local_float(0); break;
1211 case Bytecodes::_fstore_1: store_local_float(1); break;
1212 case Bytecodes::_fstore_2: store_local_float(2); break;
1213 case Bytecodes::_fstore_3: store_local_float(3); break;
1214
1215 case Bytecodes::_getfield: do_getfield(str); break;
1216 case Bytecodes::_getstatic: do_getstatic(str); break;
1217
1218 case Bytecodes::_goto:
1219 case Bytecodes::_goto_w:
1220 case Bytecodes::_nop:
1221 case Bytecodes::_return:
1222 {
1223 // do nothing.
1224 break;
1225 }
1226 case Bytecodes::_i2b:
1227 case Bytecodes::_i2c:
1228 case Bytecodes::_i2s:
1229 case Bytecodes::_ineg:
1230 {
1231 pop_int();
1232 push_int();
1233 break;
1234 }
1235 case Bytecodes::_i2d:
1236 {
1237 pop_int();
1238 push_double();
1239 break;
1240 }
1241 case Bytecodes::_i2f:
1242 {
1243 pop_int();
1244 push_float();
1245 break;
1246 }
1247 case Bytecodes::_i2l:
1248 {
1249 pop_int();
1250 push_long();
1251 break;
1252 }
1253 case Bytecodes::_iadd:
1254 case Bytecodes::_iand:
1255 case Bytecodes::_idiv:
1256 case Bytecodes::_imul:
1257 case Bytecodes::_ior:
1258 case Bytecodes::_irem:
1259 case Bytecodes::_ishl:
1260 case Bytecodes::_ishr:
1261 case Bytecodes::_isub:
1262 case Bytecodes::_iushr:
1263 case Bytecodes::_ixor:
1264 {
1265 pop_int();
1266 pop_int();
1267 push_int();
1268 break;
1269 }
1270 case Bytecodes::_if_acmpeq:
1271 case Bytecodes::_if_acmpne:
1272 {
1273 pop_object();
1274 pop_object();
1275 break;
1276 }
1277 case Bytecodes::_if_icmpeq:
1278 case Bytecodes::_if_icmpge:
1279 case Bytecodes::_if_icmpgt:
1280 case Bytecodes::_if_icmple:
1281 case Bytecodes::_if_icmplt:
1282 case Bytecodes::_if_icmpne:
1283 {
1284 pop_int();
1285 pop_int();
1286 break;
1287 }
1288 case Bytecodes::_ifeq:
1289 case Bytecodes::_ifle:
1290 case Bytecodes::_iflt:
1291 case Bytecodes::_ifge:
1292 case Bytecodes::_ifgt:
1293 case Bytecodes::_ifne:
1294 case Bytecodes::_ireturn:
1295 case Bytecodes::_lookupswitch:
1296 case Bytecodes::_tableswitch:
1297 {
1298 pop_int();
1299 break;
1300 }
1301 case Bytecodes::_iinc:
1302 {
1303 int lnum = str->get_index();
1304 check_int(local(lnum));
1305 store_to_local(lnum);
1306 break;
1307 }
1308 case Bytecodes::_iload: load_local_int(str->get_index()); break;
1309 case Bytecodes::_iload_0: load_local_int(0); break;
1310 case Bytecodes::_iload_1: load_local_int(1); break;
1311 case Bytecodes::_iload_2: load_local_int(2); break;
1312 case Bytecodes::_iload_3: load_local_int(3); break;
1313
1314 case Bytecodes::_instanceof:
1315 {
1316 // Check for uncommon trap:
1317 do_checkcast(str);
1318 pop_object();
1319 push_int();
1320 break;
1321 }
1322 case Bytecodes::_invokeinterface: do_invoke(str, true); break;
1323 case Bytecodes::_invokespecial: do_invoke(str, true); break;
1324 case Bytecodes::_invokestatic: do_invoke(str, false); break;
1325 case Bytecodes::_invokevirtual: do_invoke(str, true); break;
1326 case Bytecodes::_invokedynamic: do_invoke(str, false); break;
1327
1328 case Bytecodes::_istore: store_local_int(str->get_index()); break;
1329 case Bytecodes::_istore_0: store_local_int(0); break;
1330 case Bytecodes::_istore_1: store_local_int(1); break;
1331 case Bytecodes::_istore_2: store_local_int(2); break;
1332 case Bytecodes::_istore_3: store_local_int(3); break;
1333
1334 case Bytecodes::_jsr:
1335 case Bytecodes::_jsr_w: do_jsr(str); break;
1336
1337 case Bytecodes::_l2d:
1338 {
1339 pop_long();
1340 push_double();
1341 break;
1342 }
1343 case Bytecodes::_l2f:
1344 {
1345 pop_long();
1346 push_float();
1347 break;
1348 }
1349 case Bytecodes::_l2i:
1350 {
1351 pop_long();
1352 push_int();
1353 break;
1354 }
1355 case Bytecodes::_ladd:
1356 case Bytecodes::_land:
1357 case Bytecodes::_ldiv:
1358 case Bytecodes::_lmul:
1359 case Bytecodes::_lor:
1360 case Bytecodes::_lrem:
1361 case Bytecodes::_lsub:
1362 case Bytecodes::_lxor:
1363 {
1364 pop_long();
1365 pop_long();
1366 push_long();
1367 break;
1368 }
1369 case Bytecodes::_laload:
1370 {
1371 pop_int();
1372 ciTypeArrayKlass* array_klass = pop_typeArray();
1373 // Put assert here for right type?
1374 push_long();
1375 break;
1376 }
1377 case Bytecodes::_lastore:
1378 {
1379 pop_long();
1380 pop_int();
1381 pop_typeArray();
1382 // assert here?
1383 break;
1384 }
1385 case Bytecodes::_lcmp:
1386 {
1387 pop_long();
1388 pop_long();
1389 push_int();
1390 break;
1391 }
1392 case Bytecodes::_lconst_0:
1393 case Bytecodes::_lconst_1:
1394 {
1395 push_long();
1396 break;
1397 }
1398 case Bytecodes::_ldc:
1399 case Bytecodes::_ldc_w:
1400 case Bytecodes::_ldc2_w:
1401 {
1402 do_ldc(str);
1403 break;
1404 }
1405
1406 case Bytecodes::_lload: load_local_long(str->get_index()); break;
1407 case Bytecodes::_lload_0: load_local_long(0); break;
1408 case Bytecodes::_lload_1: load_local_long(1); break;
1409 case Bytecodes::_lload_2: load_local_long(2); break;
1410 case Bytecodes::_lload_3: load_local_long(3); break;
1411
1412 case Bytecodes::_lneg:
1413 {
1414 pop_long();
1415 push_long();
1416 break;
1417 }
1418 case Bytecodes::_lreturn:
1419 {
1420 pop_long();
1421 break;
1422 }
1423 case Bytecodes::_lshl:
1424 case Bytecodes::_lshr:
1425 case Bytecodes::_lushr:
1426 {
1427 pop_int();
1428 pop_long();
1429 push_long();
1430 break;
1431 }
1432 case Bytecodes::_lstore: store_local_long(str->get_index()); break;
1433 case Bytecodes::_lstore_0: store_local_long(0); break;
1434 case Bytecodes::_lstore_1: store_local_long(1); break;
1435 case Bytecodes::_lstore_2: store_local_long(2); break;
1436 case Bytecodes::_lstore_3: store_local_long(3); break;
1437
1438 case Bytecodes::_multianewarray: do_multianewarray(str); break;
1439
1440 case Bytecodes::_new: do_new(str); break;
1441
1442 case Bytecodes::_newarray: do_newarray(str); break;
1443
1444 case Bytecodes::_pop:
1445 {
1446 pop();
1447 break;
1448 }
1449 case Bytecodes::_pop2:
1450 {
1451 pop();
1452 pop();
1453 break;
1454 }
1455
1456 case Bytecodes::_putfield: do_putfield(str); break;
1457 case Bytecodes::_putstatic: do_putstatic(str); break;
1458
1459 case Bytecodes::_ret: do_ret(str); break;
1460
1461 case Bytecodes::_swap:
1462 {
1463 ciType* value1 = pop_value();
1464 ciType* value2 = pop_value();
1465 push(value1);
1466 push(value2);
1467 break;
1468 }
1469 case Bytecodes::_wide:
1470 default:
1471 {
1472 // The iterator should skip this.
1473 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1473); ::breakpoint(); } while (0)
;
1474 break;
1475 }
1476 }
1477
1478 if (CITraceTypeFlow) {
1479 print_on(tty);
1480 }
1481
1482 return (_trap_bci != -1);
1483}
1484
1485#ifndef PRODUCT
1486// ------------------------------------------------------------------
1487// ciTypeFlow::StateVector::print_cell_on
1488void ciTypeFlow::StateVector::print_cell_on(outputStream* st, Cell c) const {
1489 ciType* type = type_at(c);
1490 if (type == top_type()) {
1491 st->print("top");
1492 } else if (type == bottom_type()) {
1493 st->print("bottom");
1494 } else if (type == null_type()) {
1495 st->print("null");
1496 } else if (type == long2_type()) {
1497 st->print("long2");
1498 } else if (type == double2_type()) {
1499 st->print("double2");
1500 } else if (is_int(type)) {
1501 st->print("int");
1502 } else if (is_long(type)) {
1503 st->print("long");
1504 } else if (is_float(type)) {
1505 st->print("float");
1506 } else if (is_double(type)) {
1507 st->print("double");
1508 } else if (type->is_return_address()) {
1509 st->print("address(%d)", type->as_return_address()->bci());
1510 } else {
1511 if (type->is_klass()) {
1512 type->as_klass()->name()->print_symbol_on(st);
1513 } else {
1514 st->print("UNEXPECTED TYPE");
1515 type->print();
1516 }
1517 }
1518}
1519
1520// ------------------------------------------------------------------
1521// ciTypeFlow::StateVector::print_on
1522void ciTypeFlow::StateVector::print_on(outputStream* st) const {
1523 int num_locals = _outer->max_locals();
1524 int num_stack = stack_size();
1525 int num_monitors = monitor_count();
1526 st->print_cr(" State : locals %d, stack %d, monitors %d", num_locals, num_stack, num_monitors);
1527 if (num_stack >= 0) {
1528 int i;
1529 for (i = 0; i < num_locals; i++) {
1530 st->print(" local %2d : ", i);
1531 print_cell_on(st, local(i));
1532 st->cr();
1533 }
1534 for (i = 0; i < num_stack; i++) {
1535 st->print(" stack %2d : ", i);
1536 print_cell_on(st, stack(i));
1537 st->cr();
1538 }
1539 }
1540}
1541#endif
1542
1543
1544// ------------------------------------------------------------------
1545// ciTypeFlow::SuccIter::next
1546//
1547void ciTypeFlow::SuccIter::next() {
1548 int succ_ct = _pred->successors()->length();
1549 int next = _index + 1;
1550 if (next < succ_ct) {
1551 _index = next;
1552 _succ = _pred->successors()->at(next);
1553 return;
1554 }
1555 for (int i = next - succ_ct; i < _pred->exceptions()->length(); i++) {
1556 // Do not compile any code for unloaded exception types.
1557 // Following compiler passes are responsible for doing this also.
1558 ciInstanceKlass* exception_klass = _pred->exc_klasses()->at(i);
1559 if (exception_klass->is_loaded()) {
1560 _index = next;
1561 _succ = _pred->exceptions()->at(i);
1562 return;
1563 }
1564 next++;
1565 }
1566 _index = -1;
1567 _succ = NULL__null;
1568}
1569
1570// ------------------------------------------------------------------
1571// ciTypeFlow::SuccIter::set_succ
1572//
1573void ciTypeFlow::SuccIter::set_succ(Block* succ) {
1574 int succ_ct = _pred->successors()->length();
1575 if (_index < succ_ct) {
1576 _pred->successors()->at_put(_index, succ);
1577 } else {
1578 int idx = _index - succ_ct;
1579 _pred->exceptions()->at_put(idx, succ);
1580 }
1581}
1582
1583// ciTypeFlow::Block
1584//
1585// A basic block.
1586
1587// ------------------------------------------------------------------
1588// ciTypeFlow::Block::Block
1589ciTypeFlow::Block::Block(ciTypeFlow* outer,
1590 ciBlock *ciblk,
1591 ciTypeFlow::JsrSet* jsrs) : _predecessors(outer->arena(), 1, 0, NULL__null) {
1592 _ciblock = ciblk;
1593 _exceptions = NULL__null;
1594 _exc_klasses = NULL__null;
1595 _successors = NULL__null;
1596 _state = new (outer->arena()) StateVector(outer);
1597 JsrSet* new_jsrs =
1598 new (outer->arena()) JsrSet(outer->arena(), jsrs->size());
1599 jsrs->copy_into(new_jsrs);
1600 _jsrs = new_jsrs;
1601 _next = NULL__null;
1602 _on_work_list = false;
1603 _backedge_copy = false;
1604 _has_monitorenter = false;
1605 _trap_bci = -1;
1606 _trap_index = 0;
1607 df_init();
1608
1609 if (CITraceTypeFlow) {
1610 tty->print_cr(">> Created new block");
1611 print_on(tty);
1612 }
1613
1614 assert(this->outer() == outer, "outer link set up")do { if (!(this->outer() == outer)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1614, "assert(" "this->outer() == outer" ") failed", "outer link set up"
); ::breakpoint(); } } while (0)
;
1615 assert(!outer->have_block_count(), "must not have mapped blocks yet")do { if (!(!outer->have_block_count())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1615, "assert(" "!outer->have_block_count()" ") failed",
"must not have mapped blocks yet"); ::breakpoint(); } } while
(0)
;
1616}
1617
1618// ------------------------------------------------------------------
1619// ciTypeFlow::Block::df_init
1620void ciTypeFlow::Block::df_init() {
1621 _pre_order = -1; assert(!has_pre_order(), "")do { if (!(!has_pre_order())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1621, "assert(" "!has_pre_order()" ") failed", ""); ::breakpoint
(); } } while (0)
;
1622 _post_order = -1; assert(!has_post_order(), "")do { if (!(!has_post_order())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1622, "assert(" "!has_post_order()" ") failed", ""); ::breakpoint
(); } } while (0)
;
1623 _loop = NULL__null;
1624 _irreducible_entry = false;
1625 _rpo_next = NULL__null;
1626}
1627
1628// ------------------------------------------------------------------
1629// ciTypeFlow::Block::successors
1630//
1631// Get the successors for this Block.
1632GrowableArray<ciTypeFlow::Block*>*
1633ciTypeFlow::Block::successors(ciBytecodeStream* str,
1634 ciTypeFlow::StateVector* state,
1635 ciTypeFlow::JsrSet* jsrs) {
1636 if (_successors == NULL__null) {
1637 if (CITraceTypeFlow) {
1638 tty->print(">> Computing successors for block ");
1639 print_value_on(tty);
1640 tty->cr();
1641 }
1642
1643 ciTypeFlow* analyzer = outer();
1644 Arena* arena = analyzer->arena();
1645 Block* block = NULL__null;
1646 bool has_successor = !has_trap() &&
1647 (control() != ciBlock::fall_through_bci || limit() < analyzer->code_size());
1648 if (!has_successor) {
1649 _successors =
1650 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1651 // No successors
1652 } else if (control() == ciBlock::fall_through_bci) {
1653 assert(str->cur_bci() == limit(), "bad block end")do { if (!(str->cur_bci() == limit())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1653, "assert(" "str->cur_bci() == limit()" ") failed", "bad block end"
); ::breakpoint(); } } while (0)
;
1654 // This block simply falls through to the next.
1655 _successors =
1656 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1657
1658 Block* block = analyzer->block_at(limit(), _jsrs);
1659 assert(_successors->length() == FALL_THROUGH, "")do { if (!(_successors->length() == FALL_THROUGH)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1659, "assert(" "_successors->length() == FALL_THROUGH" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1660 _successors->append(block);
1661 } else {
1662 int current_bci = str->cur_bci();
1663 int next_bci = str->next_bci();
1664 int branch_bci = -1;
1665 Block* target = NULL__null;
1666 assert(str->next_bci() == limit(), "bad block end")do { if (!(str->next_bci() == limit())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1666, "assert(" "str->next_bci() == limit()" ") failed",
"bad block end"); ::breakpoint(); } } while (0)
;
1667 // This block is not a simple fall-though. Interpret
1668 // the current bytecode to find our successors.
1669 switch (str->cur_bc()) {
1670 case Bytecodes::_ifeq: case Bytecodes::_ifne:
1671 case Bytecodes::_iflt: case Bytecodes::_ifge:
1672 case Bytecodes::_ifgt: case Bytecodes::_ifle:
1673 case Bytecodes::_if_icmpeq: case Bytecodes::_if_icmpne:
1674 case Bytecodes::_if_icmplt: case Bytecodes::_if_icmpge:
1675 case Bytecodes::_if_icmpgt: case Bytecodes::_if_icmple:
1676 case Bytecodes::_if_acmpeq: case Bytecodes::_if_acmpne:
1677 case Bytecodes::_ifnull: case Bytecodes::_ifnonnull:
1678 // Our successors are the branch target and the next bci.
1679 branch_bci = str->get_dest();
1680 _successors =
1681 new (arena) GrowableArray<Block*>(arena, 2, 0, NULL__null);
1682 assert(_successors->length() == IF_NOT_TAKEN, "")do { if (!(_successors->length() == IF_NOT_TAKEN)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1682, "assert(" "_successors->length() == IF_NOT_TAKEN" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1683 _successors->append(analyzer->block_at(next_bci, jsrs));
1684 assert(_successors->length() == IF_TAKEN, "")do { if (!(_successors->length() == IF_TAKEN)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1684, "assert(" "_successors->length() == IF_TAKEN" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1685 _successors->append(analyzer->block_at(branch_bci, jsrs));
1686 break;
1687
1688 case Bytecodes::_goto:
1689 branch_bci = str->get_dest();
1690 _successors =
1691 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1692 assert(_successors->length() == GOTO_TARGET, "")do { if (!(_successors->length() == GOTO_TARGET)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1692, "assert(" "_successors->length() == GOTO_TARGET" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1693 _successors->append(analyzer->block_at(branch_bci, jsrs));
1694 break;
1695
1696 case Bytecodes::_jsr:
1697 branch_bci = str->get_dest();
1698 _successors =
1699 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1700 assert(_successors->length() == GOTO_TARGET, "")do { if (!(_successors->length() == GOTO_TARGET)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1700, "assert(" "_successors->length() == GOTO_TARGET" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1701 _successors->append(analyzer->block_at(branch_bci, jsrs));
1702 break;
1703
1704 case Bytecodes::_goto_w:
1705 case Bytecodes::_jsr_w:
1706 _successors =
1707 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1708 assert(_successors->length() == GOTO_TARGET, "")do { if (!(_successors->length() == GOTO_TARGET)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1708, "assert(" "_successors->length() == GOTO_TARGET" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1709 _successors->append(analyzer->block_at(str->get_far_dest(), jsrs));
1710 break;
1711
1712 case Bytecodes::_tableswitch: {
1713 Bytecode_tableswitch tableswitch(str);
1714
1715 int len = tableswitch.length();
1716 _successors =
1717 new (arena) GrowableArray<Block*>(arena, len+1, 0, NULL__null);
1718 int bci = current_bci + tableswitch.default_offset();
1719 Block* block = analyzer->block_at(bci, jsrs);
1720 assert(_successors->length() == SWITCH_DEFAULT, "")do { if (!(_successors->length() == SWITCH_DEFAULT)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1720, "assert(" "_successors->length() == SWITCH_DEFAULT"
") failed", ""); ::breakpoint(); } } while (0)
;
1721 _successors->append(block);
1722 while (--len >= 0) {
1723 int bci = current_bci + tableswitch.dest_offset_at(len);
1724 block = analyzer->block_at(bci, jsrs);
1725 assert(_successors->length() >= SWITCH_CASES, "")do { if (!(_successors->length() >= SWITCH_CASES)) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1725, "assert(" "_successors->length() >= SWITCH_CASES"
") failed", ""); ::breakpoint(); } } while (0)
;
1726 _successors->append_if_missing(block);
1727 }
1728 break;
1729 }
1730
1731 case Bytecodes::_lookupswitch: {
1732 Bytecode_lookupswitch lookupswitch(str);
1733
1734 int npairs = lookupswitch.number_of_pairs();
1735 _successors =
1736 new (arena) GrowableArray<Block*>(arena, npairs+1, 0, NULL__null);
1737 int bci = current_bci + lookupswitch.default_offset();
1738 Block* block = analyzer->block_at(bci, jsrs);
1739 assert(_successors->length() == SWITCH_DEFAULT, "")do { if (!(_successors->length() == SWITCH_DEFAULT)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1739, "assert(" "_successors->length() == SWITCH_DEFAULT"
") failed", ""); ::breakpoint(); } } while (0)
;
1740 _successors->append(block);
1741 while(--npairs >= 0) {
1742 LookupswitchPair pair = lookupswitch.pair_at(npairs);
1743 int bci = current_bci + pair.offset();
1744 Block* block = analyzer->block_at(bci, jsrs);
1745 assert(_successors->length() >= SWITCH_CASES, "")do { if (!(_successors->length() >= SWITCH_CASES)) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1745, "assert(" "_successors->length() >= SWITCH_CASES"
") failed", ""); ::breakpoint(); } } while (0)
;
1746 _successors->append_if_missing(block);
1747 }
1748 break;
1749 }
1750
1751 case Bytecodes::_athrow: case Bytecodes::_ireturn:
1752 case Bytecodes::_lreturn: case Bytecodes::_freturn:
1753 case Bytecodes::_dreturn: case Bytecodes::_areturn:
1754 case Bytecodes::_return:
1755 _successors =
1756 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1757 // No successors
1758 break;
1759
1760 case Bytecodes::_ret: {
1761 _successors =
1762 new (arena) GrowableArray<Block*>(arena, 1, 0, NULL__null);
1763
1764 Cell local = state->local(str->get_index());
1765 ciType* return_address = state->type_at(local);
1766 assert(return_address->is_return_address(), "verify: wrong type")do { if (!(return_address->is_return_address())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1766, "assert(" "return_address->is_return_address()" ") failed"
, "verify: wrong type"); ::breakpoint(); } } while (0)
;
1767 int bci = return_address->as_return_address()->bci();
1768 assert(_successors->length() == GOTO_TARGET, "")do { if (!(_successors->length() == GOTO_TARGET)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1768, "assert(" "_successors->length() == GOTO_TARGET" ") failed"
, ""); ::breakpoint(); } } while (0)
;
1769 _successors->append(analyzer->block_at(bci, jsrs));
1770 break;
1771 }
1772
1773 case Bytecodes::_wide:
1774 default:
1775 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1775); ::breakpoint(); } while (0)
;
1776 break;
1777 }
1778 }
1779
1780 // Set predecessor information
1781 for (int i = 0; i < _successors->length(); i++) {
1782 Block* block = _successors->at(i);
1783 block->predecessors()->append(this);
1784 }
1785 }
1786 return _successors;
1787}
1788
1789// ------------------------------------------------------------------
1790// ciTypeFlow::Block:compute_exceptions
1791//
1792// Compute the exceptional successors and types for this Block.
1793void ciTypeFlow::Block::compute_exceptions() {
1794 assert(_exceptions == NULL && _exc_klasses == NULL, "repeat")do { if (!(_exceptions == __null && _exc_klasses == __null
)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1794, "assert(" "_exceptions == __null && _exc_klasses == __null"
") failed", "repeat"); ::breakpoint(); } } while (0)
;
1795
1796 if (CITraceTypeFlow) {
1797 tty->print(">> Computing exceptions for block ");
1798 print_value_on(tty);
1799 tty->cr();
1800 }
1801
1802 ciTypeFlow* analyzer = outer();
1803 Arena* arena = analyzer->arena();
1804
1805 // Any bci in the block will do.
1806 ciExceptionHandlerStream str(analyzer->method(), start());
1807
1808 // Allocate our growable arrays.
1809 int exc_count = str.count();
1810 _exceptions = new (arena) GrowableArray<Block*>(arena, exc_count, 0, NULL__null);
1811 _exc_klasses = new (arena) GrowableArray<ciInstanceKlass*>(arena, exc_count,
1812 0, NULL__null);
1813
1814 for ( ; !str.is_done(); str.next()) {
1815 ciExceptionHandler* handler = str.handler();
1816 int bci = handler->handler_bci();
1817 ciInstanceKlass* klass = NULL__null;
1818 if (bci == -1) {
1819 // There is no catch all. It is possible to exit the method.
1820 break;
1821 }
1822 if (handler->is_catch_all()) {
1823 klass = analyzer->env()->Throwable_klass();
1824 } else {
1825 klass = handler->catch_klass();
1826 }
1827 Block* block = analyzer->block_at(bci, _jsrs);
1828 _exceptions->append(block);
1829 block->predecessors()->append(this);
1830 _exc_klasses->append(klass);
1831 }
1832}
1833
1834// ------------------------------------------------------------------
1835// ciTypeFlow::Block::set_backedge_copy
1836// Use this only to make a pre-existing public block into a backedge copy.
1837void ciTypeFlow::Block::set_backedge_copy(bool z) {
1838 assert(z || (z == is_backedge_copy()), "cannot make a backedge copy public")do { if (!(z || (z == is_backedge_copy()))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1838, "assert(" "z || (z == is_backedge_copy())" ") failed"
, "cannot make a backedge copy public"); ::breakpoint(); } } while
(0)
;
1839 _backedge_copy = z;
1840}
1841
1842// ------------------------------------------------------------------
1843// ciTypeFlow::Block::is_clonable_exit
1844//
1845// At most 2 normal successors, one of which continues looping,
1846// and all exceptional successors must exit.
1847bool ciTypeFlow::Block::is_clonable_exit(ciTypeFlow::Loop* lp) {
1848 int normal_cnt = 0;
1849 int in_loop_cnt = 0;
1850 for (SuccIter iter(this); !iter.done(); iter.next()) {
1851 Block* succ = iter.succ();
1852 if (iter.is_normal_ctrl()) {
1853 if (++normal_cnt > 2) return false;
1854 if (lp->contains(succ->loop())) {
1855 if (++in_loop_cnt > 1) return false;
1856 }
1857 } else {
1858 if (lp->contains(succ->loop())) return false;
1859 }
1860 }
1861 return in_loop_cnt == 1;
1862}
1863
1864// ------------------------------------------------------------------
1865// ciTypeFlow::Block::looping_succ
1866//
1867ciTypeFlow::Block* ciTypeFlow::Block::looping_succ(ciTypeFlow::Loop* lp) {
1868 assert(successors()->length() <= 2, "at most 2 normal successors")do { if (!(successors()->length() <= 2)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1868, "assert(" "successors()->length() <= 2" ") failed"
, "at most 2 normal successors"); ::breakpoint(); } } while (
0)
;
1869 for (SuccIter iter(this); !iter.done(); iter.next()) {
1870 Block* succ = iter.succ();
1871 if (lp->contains(succ->loop())) {
1872 return succ;
1873 }
1874 }
1875 return NULL__null;
1876}
1877
1878#ifndef PRODUCT
1879// ------------------------------------------------------------------
1880// ciTypeFlow::Block::print_value_on
1881void ciTypeFlow::Block::print_value_on(outputStream* st) const {
1882 if (has_pre_order()) st->print("#%-2d ", pre_order());
1883 if (has_rpo()) st->print("rpo#%-2d ", rpo());
1884 st->print("[%d - %d)", start(), limit());
1885 if (is_loop_head()) st->print(" lphd");
1886 if (is_irreducible_entry()) st->print(" irred");
1887 if (_jsrs->size() > 0) { st->print("/"); _jsrs->print_on(st); }
1888 if (is_backedge_copy()) st->print("/backedge_copy");
1889}
1890
1891// ------------------------------------------------------------------
1892// ciTypeFlow::Block::print_on
1893void ciTypeFlow::Block::print_on(outputStream* st) const {
1894 if ((Verbose || WizardMode) && (limit() >= 0)) {
1895 // Don't print 'dummy' blocks (i.e. blocks with limit() '-1')
1896 outer()->method()->print_codes_on(start(), limit(), st);
1897 }
1898 st->print_cr(" ==================================================== ");
1899 st->print (" ");
1900 print_value_on(st);
1901 st->print(" Stored locals: "); def_locals()->print_on(st, outer()->method()->max_locals()); tty->cr();
1902 if (loop() && loop()->parent() != NULL__null) {
1903 st->print(" loops:");
1904 Loop* lp = loop();
1905 do {
1906 st->print(" %d<-%d", lp->head()->pre_order(),lp->tail()->pre_order());
1907 if (lp->is_irreducible()) st->print("(ir)");
1908 lp = lp->parent();
1909 } while (lp->parent() != NULL__null);
1910 }
1911 st->cr();
1912 _state->print_on(st);
1913 if (_successors == NULL__null) {
1914 st->print_cr(" No successor information");
1915 } else {
1916 int num_successors = _successors->length();
1917 st->print_cr(" Successors : %d", num_successors);
1918 for (int i = 0; i < num_successors; i++) {
1919 Block* successor = _successors->at(i);
1920 st->print(" ");
1921 successor->print_value_on(st);
1922 st->cr();
1923 }
1924 }
1925 if (_predecessors.is_empty()) {
1926 st->print_cr(" No predecessor information");
1927 } else {
1928 int num_predecessors = _predecessors.length();
1929 st->print_cr(" Predecessors : %d", num_predecessors);
1930 for (int i = 0; i < num_predecessors; i++) {
1931 Block* predecessor = _predecessors.at(i);
1932 st->print(" ");
1933 predecessor->print_value_on(st);
1934 st->cr();
1935 }
1936 }
1937 if (_exceptions == NULL__null) {
1938 st->print_cr(" No exception information");
1939 } else {
1940 int num_exceptions = _exceptions->length();
1941 st->print_cr(" Exceptions : %d", num_exceptions);
1942 for (int i = 0; i < num_exceptions; i++) {
1943 Block* exc_succ = _exceptions->at(i);
1944 ciInstanceKlass* exc_klass = _exc_klasses->at(i);
1945 st->print(" ");
1946 exc_succ->print_value_on(st);
1947 st->print(" -- ");
1948 exc_klass->name()->print_symbol_on(st);
1949 st->cr();
1950 }
1951 }
1952 if (has_trap()) {
1953 st->print_cr(" Traps on %d with trap index %d", trap_bci(), trap_index());
1954 }
1955 st->print_cr(" ==================================================== ");
1956}
1957#endif
1958
1959#ifndef PRODUCT
1960// ------------------------------------------------------------------
1961// ciTypeFlow::LocalSet::print_on
1962void ciTypeFlow::LocalSet::print_on(outputStream* st, int limit) const {
1963 st->print("{");
1964 for (int i = 0; i < max; i++) {
1965 if (test(i)) st->print(" %d", i);
1966 }
1967 if (limit > max) {
1968 st->print(" %d..%d ", max, limit);
1969 }
1970 st->print(" }");
1971}
1972#endif
1973
1974// ciTypeFlow
1975//
1976// This is a pass over the bytecodes which computes the following:
1977// basic block structure
1978// interpreter type-states (a la the verifier)
1979
1980// ------------------------------------------------------------------
1981// ciTypeFlow::ciTypeFlow
1982ciTypeFlow::ciTypeFlow(ciEnv* env, ciMethod* method, int osr_bci) {
1983 _env = env;
1984 _method = method;
1985 _has_irreducible_entry = false;
1986 _osr_bci = osr_bci;
1987 _failure_reason = NULL__null;
1988 assert(0 <= start_bci() && start_bci() < code_size() , "correct osr_bci argument: 0 <= %d < %d", start_bci(), code_size())do { if (!(0 <= start_bci() && start_bci() < code_size
())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 1988, "assert(" "0 <= start_bci() && start_bci() < code_size()"
") failed", "correct osr_bci argument: 0 <= %d < %d", start_bci
(), code_size()); ::breakpoint(); } } while (0)
;
1989 _work_list = NULL__null;
1990
1991 int ciblock_count = _method->get_method_blocks()->num_blocks();
1992 _idx_to_blocklist = NEW_ARENA_ARRAY(arena(), GrowableArray<Block*>*, ciblock_count)(GrowableArray<Block*>**) (arena())->Amalloc((ciblock_count
) * sizeof(GrowableArray<Block*>*))
;
1993 for (int i = 0; i < ciblock_count; i++) {
1994 _idx_to_blocklist[i] = NULL__null;
1995 }
1996 _block_map = NULL__null; // until all blocks are seen
1997 _jsr_records = NULL__null;
1998}
1999
2000// ------------------------------------------------------------------
2001// ciTypeFlow::work_list_next
2002//
2003// Get the next basic block from our work list.
2004ciTypeFlow::Block* ciTypeFlow::work_list_next() {
2005 assert(!work_list_empty(), "work list must not be empty")do { if (!(!work_list_empty())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2005, "assert(" "!work_list_empty()" ") failed", "work list must not be empty"
); ::breakpoint(); } } while (0)
;
2006 Block* next_block = _work_list;
2007 _work_list = next_block->next();
2008 next_block->set_next(NULL__null);
2009 next_block->set_on_work_list(false);
2010 return next_block;
2011}
2012
2013// ------------------------------------------------------------------
2014// ciTypeFlow::add_to_work_list
2015//
2016// Add a basic block to our work list.
2017// List is sorted by decreasing postorder sort (same as increasing RPO)
2018void ciTypeFlow::add_to_work_list(ciTypeFlow::Block* block) {
2019 assert(!block->is_on_work_list(), "must not already be on work list")do { if (!(!block->is_on_work_list())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2019, "assert(" "!block->is_on_work_list()" ") failed", "must not already be on work list"
); ::breakpoint(); } } while (0)
;
2020
2021 if (CITraceTypeFlow) {
2022 tty->print(">> Adding block ");
2023 block->print_value_on(tty);
2024 tty->print_cr(" to the work list : ");
2025 }
2026
2027 block->set_on_work_list(true);
2028
2029 // decreasing post order sort
2030
2031 Block* prev = NULL__null;
2032 Block* current = _work_list;
2033 int po = block->post_order();
2034 while (current != NULL__null) {
2035 if (!current->has_post_order() || po > current->post_order())
2036 break;
2037 prev = current;
2038 current = current->next();
2039 }
2040 if (prev == NULL__null) {
2041 block->set_next(_work_list);
2042 _work_list = block;
2043 } else {
2044 block->set_next(current);
2045 prev->set_next(block);
2046 }
2047
2048 if (CITraceTypeFlow) {
2049 tty->cr();
2050 }
2051}
2052
2053// ------------------------------------------------------------------
2054// ciTypeFlow::block_at
2055//
2056// Return the block beginning at bci which has a JsrSet compatible
2057// with jsrs.
2058ciTypeFlow::Block* ciTypeFlow::block_at(int bci, ciTypeFlow::JsrSet* jsrs, CreateOption option) {
2059 // First find the right ciBlock.
2060 if (CITraceTypeFlow) {
2061 tty->print(">> Requesting block for %d/", bci);
2062 jsrs->print_on(tty);
2063 tty->cr();
2064 }
2065
2066 ciBlock* ciblk = _method->get_method_blocks()->block_containing(bci);
2067 assert(ciblk->start_bci() == bci, "bad ciBlock boundaries")do { if (!(ciblk->start_bci() == bci)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2067, "assert(" "ciblk->start_bci() == bci" ") failed", "bad ciBlock boundaries"
); ::breakpoint(); } } while (0)
;
2068 Block* block = get_block_for(ciblk->index(), jsrs, option);
2069
2070 assert(block == NULL? (option == no_create): block->is_backedge_copy() == (option == create_backedge_copy), "create option consistent with result")do { if (!(block == __null? (option == no_create): block->
is_backedge_copy() == (option == create_backedge_copy))) { (*
g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2070, "assert(" "block == __null? (option == no_create): block->is_backedge_copy() == (option == create_backedge_copy)"
") failed", "create option consistent with result"); ::breakpoint
(); } } while (0)
;
2071
2072 if (CITraceTypeFlow) {
2073 if (block != NULL__null) {
2074 tty->print(">> Found block ");
2075 block->print_value_on(tty);
2076 tty->cr();
2077 } else {
2078 tty->print_cr(">> No such block.");
2079 }
2080 }
2081
2082 return block;
2083}
2084
2085// ------------------------------------------------------------------
2086// ciTypeFlow::make_jsr_record
2087//
2088// Make a JsrRecord for a given (entry, return) pair, if such a record
2089// does not already exist.
2090ciTypeFlow::JsrRecord* ciTypeFlow::make_jsr_record(int entry_address,
2091 int return_address) {
2092 if (_jsr_records == NULL__null) {
2093 _jsr_records = new (arena()) GrowableArray<JsrRecord*>(arena(),
2094 2,
2095 0,
2096 NULL__null);
2097 }
2098 JsrRecord* record = NULL__null;
2099 int len = _jsr_records->length();
2100 for (int i = 0; i < len; i++) {
2101 JsrRecord* record = _jsr_records->at(i);
2102 if (record->entry_address() == entry_address &&
2103 record->return_address() == return_address) {
2104 return record;
2105 }
2106 }
2107
2108 record = new (arena()) JsrRecord(entry_address, return_address);
2109 _jsr_records->append(record);
2110 return record;
2111}
2112
2113// ------------------------------------------------------------------
2114// ciTypeFlow::flow_exceptions
2115//
2116// Merge the current state into all exceptional successors at the
2117// current point in the code.
2118void ciTypeFlow::flow_exceptions(GrowableArray<ciTypeFlow::Block*>* exceptions,
2119 GrowableArray<ciInstanceKlass*>* exc_klasses,
2120 ciTypeFlow::StateVector* state) {
2121 int len = exceptions->length();
2122 assert(exc_klasses->length() == len, "must have same length")do { if (!(exc_klasses->length() == len)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2122, "assert(" "exc_klasses->length() == len" ") failed"
, "must have same length"); ::breakpoint(); } } while (0)
;
2123 for (int i = 0; i < len; i++) {
2124 Block* block = exceptions->at(i);
2125 ciInstanceKlass* exception_klass = exc_klasses->at(i);
2126
2127 if (!exception_klass->is_loaded()) {
2128 // Do not compile any code for unloaded exception types.
2129 // Following compiler passes are responsible for doing this also.
2130 continue;
2131 }
2132
2133 if (block->meet_exception(exception_klass, state)) {
2134 // Block was modified and has PO. Add it to the work list.
2135 if (block->has_post_order() &&
2136 !block->is_on_work_list()) {
2137 add_to_work_list(block);
2138 }
2139 }
2140 }
2141}
2142
2143// ------------------------------------------------------------------
2144// ciTypeFlow::flow_successors
2145//
2146// Merge the current state into all successors at the current point
2147// in the code.
2148void ciTypeFlow::flow_successors(GrowableArray<ciTypeFlow::Block*>* successors,
2149 ciTypeFlow::StateVector* state) {
2150 int len = successors->length();
2151 for (int i = 0; i < len; i++) {
2152 Block* block = successors->at(i);
2153 if (block->meet(state)) {
2154 // Block was modified and has PO. Add it to the work list.
2155 if (block->has_post_order() &&
2156 !block->is_on_work_list()) {
2157 add_to_work_list(block);
2158 }
2159 }
2160 }
2161}
2162
2163// ------------------------------------------------------------------
2164// ciTypeFlow::can_trap
2165//
2166// Tells if a given instruction is able to generate an exception edge.
2167bool ciTypeFlow::can_trap(ciBytecodeStream& str) {
2168 // Cf. GenerateOopMap::do_exception_edge.
2169 if (!Bytecodes::can_trap(str.cur_bc())) return false;
2170
2171 switch (str.cur_bc()) {
2172 // %%% FIXME: ldc of Class can generate an exception
2173 case Bytecodes::_ldc:
2174 case Bytecodes::_ldc_w:
2175 case Bytecodes::_ldc2_w:
2176 return str.is_unresolved_klass_in_error();
2177
2178 case Bytecodes::_aload_0:
2179 // These bytecodes can trap for rewriting. We need to assume that
2180 // they do not throw exceptions to make the monitor analysis work.
2181 return false;
2182
2183 case Bytecodes::_ireturn:
2184 case Bytecodes::_lreturn:
2185 case Bytecodes::_freturn:
2186 case Bytecodes::_dreturn:
2187 case Bytecodes::_areturn:
2188 case Bytecodes::_return:
2189 // We can assume the monitor stack is empty in this analysis.
2190 return false;
2191
2192 case Bytecodes::_monitorexit:
2193 // We can assume monitors are matched in this analysis.
2194 return false;
2195
2196 default:
2197 return true;
2198 }
2199}
2200
2201// ------------------------------------------------------------------
2202// ciTypeFlow::clone_loop_heads
2203//
2204// Clone the loop heads
2205bool ciTypeFlow::clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set) {
2206 bool rslt = false;
2207 for (PreorderLoops iter(loop_tree_root()); !iter.done(); iter.next()) {
2208 lp = iter.current();
2209 Block* head = lp->head();
2210 if (lp == loop_tree_root() ||
2211 lp->is_irreducible() ||
2212 !head->is_clonable_exit(lp))
2213 continue;
2214
2215 // Avoid BoxLock merge.
2216 if (EliminateNestedLocks && head->has_monitorenter())
2217 continue;
2218
2219 // check not already cloned
2220 if (head->backedge_copy_count() != 0)
2221 continue;
2222
2223 // Don't clone head of OSR loop to get correct types in start block.
2224 if (is_osr_flow() && head->start() == start_bci())
2225 continue;
2226
2227 // check _no_ shared head below us
2228 Loop* ch;
2229 for (ch = lp->child(); ch != NULL__null && ch->head() != head; ch = ch->sibling());
2230 if (ch != NULL__null)
2231 continue;
2232
2233 // Clone head
2234 Block* new_head = head->looping_succ(lp);
2235 Block* clone = clone_loop_head(lp, temp_vector, temp_set);
2236 // Update lp's info
2237 clone->set_loop(lp);
2238 lp->set_head(new_head);
2239 lp->set_tail(clone);
2240 // And move original head into outer loop
2241 head->set_loop(lp->parent());
2242
2243 rslt = true;
2244 }
2245 return rslt;
2246}
2247
2248// ------------------------------------------------------------------
2249// ciTypeFlow::clone_loop_head
2250//
2251// Clone lp's head and replace tail's successors with clone.
2252//
2253// |
2254// v
2255// head <-> body
2256// |
2257// v
2258// exit
2259//
2260// new_head
2261//
2262// |
2263// v
2264// head ----------\
2265// | |
2266// | v
2267// | clone <-> body
2268// | |
2269// | /--/
2270// | |
2271// v v
2272// exit
2273//
2274ciTypeFlow::Block* ciTypeFlow::clone_loop_head(Loop* lp, StateVector* temp_vector, JsrSet* temp_set) {
2275 Block* head = lp->head();
2276 Block* tail = lp->tail();
2277 if (CITraceTypeFlow) {
2278 tty->print(">> Requesting clone of loop head "); head->print_value_on(tty);
2279 tty->print(" for predecessor "); tail->print_value_on(tty);
2280 tty->cr();
2281 }
2282 Block* clone = block_at(head->start(), head->jsrs(), create_backedge_copy);
2283 assert(clone->backedge_copy_count() == 1, "one backedge copy for all back edges")do { if (!(clone->backedge_copy_count() == 1)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2283, "assert(" "clone->backedge_copy_count() == 1" ") failed"
, "one backedge copy for all back edges"); ::breakpoint(); } }
while (0)
;
2284
2285 assert(!clone->has_pre_order(), "just created")do { if (!(!clone->has_pre_order())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2285, "assert(" "!clone->has_pre_order()" ") failed", "just created"
); ::breakpoint(); } } while (0)
;
2286 clone->set_next_pre_order();
2287
2288 // Insert clone after (orig) tail in reverse post order
2289 clone->set_rpo_next(tail->rpo_next());
2290 tail->set_rpo_next(clone);
2291
2292 // tail->head becomes tail->clone
2293 for (SuccIter iter(tail); !iter.done(); iter.next()) {
2294 if (iter.succ() == head) {
2295 iter.set_succ(clone);
2296 // Update predecessor information
2297 head->predecessors()->remove(tail);
2298 clone->predecessors()->append(tail);
2299 }
2300 }
2301 flow_block(tail, temp_vector, temp_set);
2302 if (head == tail) {
2303 // For self-loops, clone->head becomes clone->clone
2304 flow_block(clone, temp_vector, temp_set);
2305 for (SuccIter iter(clone); !iter.done(); iter.next()) {
2306 if (iter.succ() == head) {
2307 iter.set_succ(clone);
2308 // Update predecessor information
2309 head->predecessors()->remove(clone);
2310 clone->predecessors()->append(clone);
2311 break;
2312 }
2313 }
2314 }
2315 flow_block(clone, temp_vector, temp_set);
2316
2317 return clone;
2318}
2319
2320// ------------------------------------------------------------------
2321// ciTypeFlow::flow_block
2322//
2323// Interpret the effects of the bytecodes on the incoming state
2324// vector of a basic block. Push the changed state to succeeding
2325// basic blocks.
2326void ciTypeFlow::flow_block(ciTypeFlow::Block* block,
2327 ciTypeFlow::StateVector* state,
2328 ciTypeFlow::JsrSet* jsrs) {
2329 if (CITraceTypeFlow) {
2330 tty->print("\n>> ANALYZING BLOCK : ");
2331 tty->cr();
2332 block->print_on(tty);
2333 }
2334 assert(block->has_pre_order(), "pre-order is assigned before 1st flow")do { if (!(block->has_pre_order())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2334, "assert(" "block->has_pre_order()" ") failed", "pre-order is assigned before 1st flow"
); ::breakpoint(); } } while (0)
;
2335
2336 int start = block->start();
2337 int limit = block->limit();
2338 int control = block->control();
2339 if (control != ciBlock::fall_through_bci) {
2340 limit = control;
2341 }
2342
2343 // Grab the state from the current block.
2344 block->copy_state_into(state);
2345 state->def_locals()->clear();
2346
2347 GrowableArray<Block*>* exceptions = block->exceptions();
2348 GrowableArray<ciInstanceKlass*>* exc_klasses = block->exc_klasses();
2349 bool has_exceptions = exceptions->length() > 0;
2350
2351 bool exceptions_used = false;
2352
2353 ciBytecodeStream str(method());
2354 str.reset_to_bci(start);
2355 Bytecodes::Code code;
2356 while ((code = str.next()) != ciBytecodeStream::EOBC() &&
Although the value stored to 'code' is used in the enclosing expression, the value is never actually read from 'code'
2357 str.cur_bci() < limit) {
2358 // Check for exceptional control flow from this point.
2359 if (has_exceptions && can_trap(str)) {
2360 flow_exceptions(exceptions, exc_klasses, state);
2361 exceptions_used = true;
2362 }
2363 // Apply the effects of the current bytecode to our state.
2364 bool res = state->apply_one_bytecode(&str);
2365
2366 // Watch for bailouts.
2367 if (failing()) return;
2368
2369 if (str.cur_bc() == Bytecodes::_monitorenter) {
2370 block->set_has_monitorenter();
2371 }
2372
2373 if (res) {
2374
2375 // We have encountered a trap. Record it in this block.
2376 block->set_trap(state->trap_bci(), state->trap_index());
2377
2378 if (CITraceTypeFlow) {
2379 tty->print_cr(">> Found trap");
2380 block->print_on(tty);
2381 }
2382
2383 // Save set of locals defined in this block
2384 block->def_locals()->add(state->def_locals());
2385
2386 // Record (no) successors.
2387 block->successors(&str, state, jsrs);
2388
2389 assert(!has_exceptions || exceptions_used, "Not removing exceptions")do { if (!(!has_exceptions || exceptions_used)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2389, "assert(" "!has_exceptions || exceptions_used" ") failed"
, "Not removing exceptions"); ::breakpoint(); } } while (0)
;
2390
2391 // Discontinue interpretation of this Block.
2392 return;
2393 }
2394 }
2395
2396 GrowableArray<Block*>* successors = NULL__null;
2397 if (control != ciBlock::fall_through_bci) {
2398 // Check for exceptional control flow from this point.
2399 if (has_exceptions && can_trap(str)) {
2400 flow_exceptions(exceptions, exc_klasses, state);
2401 exceptions_used = true;
2402 }
2403
2404 // Fix the JsrSet to reflect effect of the bytecode.
2405 block->copy_jsrs_into(jsrs);
2406 jsrs->apply_control(this, &str, state);
2407
2408 // Find successor edges based on old state and new JsrSet.
2409 successors = block->successors(&str, state, jsrs);
2410
2411 // Apply the control changes to the state.
2412 state->apply_one_bytecode(&str);
2413 } else {
2414 // Fall through control
2415 successors = block->successors(&str, NULL__null, NULL__null);
2416 }
2417
2418 // Save set of locals defined in this block
2419 block->def_locals()->add(state->def_locals());
2420
2421 // Remove untaken exception paths
2422 if (!exceptions_used)
2423 exceptions->clear();
2424
2425 // Pass our state to successors.
2426 flow_successors(successors, state);
2427}
2428
2429// ------------------------------------------------------------------
2430// ciTypeFlow::PreOrderLoops::next
2431//
2432// Advance to next loop tree using a preorder, left-to-right traversal.
2433void ciTypeFlow::PreorderLoops::next() {
2434 assert(!done(), "must not be done.")do { if (!(!done())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2434, "assert(" "!done()" ") failed", "must not be done.");
::breakpoint(); } } while (0)
;
2435 if (_current->child() != NULL__null) {
2436 _current = _current->child();
2437 } else if (_current->sibling() != NULL__null) {
2438 _current = _current->sibling();
2439 } else {
2440 while (_current != _root && _current->sibling() == NULL__null) {
2441 _current = _current->parent();
2442 }
2443 if (_current == _root) {
2444 _current = NULL__null;
2445 assert(done(), "must be done.")do { if (!(done())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2445, "assert(" "done()" ") failed", "must be done."); ::breakpoint
(); } } while (0)
;
2446 } else {
2447 assert(_current->sibling() != NULL, "must be more to do")do { if (!(_current->sibling() != __null)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2447, "assert(" "_current->sibling() != __null" ") failed"
, "must be more to do"); ::breakpoint(); } } while (0)
;
2448 _current = _current->sibling();
2449 }
2450 }
2451}
2452
2453// ------------------------------------------------------------------
2454// ciTypeFlow::Loop::sorted_merge
2455//
2456// Merge the branch lp into this branch, sorting on the loop head
2457// pre_orders. Returns the leaf of the merged branch.
2458// Child and sibling pointers will be setup later.
2459// Sort is (looking from leaf towards the root)
2460// descending on primary key: loop head's pre_order, and
2461// ascending on secondary key: loop tail's pre_order.
2462ciTypeFlow::Loop* ciTypeFlow::Loop::sorted_merge(Loop* lp) {
2463 Loop* leaf = this;
2464 Loop* prev = NULL__null;
2465 Loop* current = leaf;
2466 while (lp != NULL__null) {
2467 int lp_pre_order = lp->head()->pre_order();
2468 // Find insertion point for "lp"
2469 while (current != NULL__null) {
2470 if (current == lp)
2471 return leaf; // Already in list
2472 if (current->head()->pre_order() < lp_pre_order)
2473 break;
2474 if (current->head()->pre_order() == lp_pre_order &&
2475 current->tail()->pre_order() > lp->tail()->pre_order()) {
2476 break;
2477 }
2478 prev = current;
2479 current = current->parent();
2480 }
2481 Loop* next_lp = lp->parent(); // Save future list of items to insert
2482 // Insert lp before current
2483 lp->set_parent(current);
2484 if (prev != NULL__null) {
2485 prev->set_parent(lp);
2486 } else {
2487 leaf = lp;
2488 }
2489 prev = lp; // Inserted item is new prev[ious]
2490 lp = next_lp; // Next item to insert
2491 }
2492 return leaf;
2493}
2494
2495// ------------------------------------------------------------------
2496// ciTypeFlow::build_loop_tree
2497//
2498// Incrementally build loop tree.
2499void ciTypeFlow::build_loop_tree(Block* blk) {
2500 assert(!blk->is_post_visited(), "precondition")do { if (!(!blk->is_post_visited())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2500, "assert(" "!blk->is_post_visited()" ") failed", "precondition"
); ::breakpoint(); } } while (0)
;
2501 Loop* innermost = NULL__null; // merge of loop tree branches over all successors
2502
2503 for (SuccIter iter(blk); !iter.done(); iter.next()) {
2504 Loop* lp = NULL__null;
2505 Block* succ = iter.succ();
2506 if (!succ->is_post_visited()) {
2507 // Found backedge since predecessor post visited, but successor is not
2508 assert(succ->pre_order() <= blk->pre_order(), "should be backedge")do { if (!(succ->pre_order() <= blk->pre_order())) {
(*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2508, "assert(" "succ->pre_order() <= blk->pre_order()"
") failed", "should be backedge"); ::breakpoint(); } } while
(0)
;
2509
2510 // Create a LoopNode to mark this loop.
2511 lp = new (arena()) Loop(succ, blk);
2512 if (succ->loop() == NULL__null)
2513 succ->set_loop(lp);
2514 // succ->loop will be updated to innermost loop on a later call, when blk==succ
2515
2516 } else { // Nested loop
2517 lp = succ->loop();
2518
2519 // If succ is loop head, find outer loop.
2520 while (lp != NULL__null && lp->head() == succ) {
2521 lp = lp->parent();
2522 }
2523 if (lp == NULL__null) {
2524 // Infinite loop, it's parent is the root
2525 lp = loop_tree_root();
2526 }
2527 }
2528
2529 // Check for irreducible loop.
2530 // Successor has already been visited. If the successor's loop head
2531 // has already been post-visited, then this is another entry into the loop.
2532 while (lp->head()->is_post_visited() && lp != loop_tree_root()) {
2533 _has_irreducible_entry = true;
2534 lp->set_irreducible(succ);
2535 if (!succ->is_on_work_list()) {
2536 // Assume irreducible entries need more data flow
2537 add_to_work_list(succ);
2538 }
2539 Loop* plp = lp->parent();
2540 if (plp == NULL__null) {
2541 // This only happens for some irreducible cases. The parent
2542 // will be updated during a later pass.
2543 break;
2544 }
2545 lp = plp;
2546 }
2547
2548 // Merge loop tree branch for all successors.
2549 innermost = innermost == NULL__null ? lp : innermost->sorted_merge(lp);
2550
2551 } // end loop
2552
2553 if (innermost == NULL__null) {
2554 assert(blk->successors()->length() == 0, "CFG exit")do { if (!(blk->successors()->length() == 0)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2554, "assert(" "blk->successors()->length() == 0" ") failed"
, "CFG exit"); ::breakpoint(); } } while (0)
;
2555 blk->set_loop(loop_tree_root());
2556 } else if (innermost->head() == blk) {
2557 // If loop header, complete the tree pointers
2558 if (blk->loop() != innermost) {
2559#ifdef ASSERT1
2560 assert(blk->loop()->head() == innermost->head(), "same head")do { if (!(blk->loop()->head() == innermost->head())
) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2560, "assert(" "blk->loop()->head() == innermost->head()"
") failed", "same head"); ::breakpoint(); } } while (0)
;
2561 Loop* dl;
2562 for (dl = innermost; dl != NULL__null && dl != blk->loop(); dl = dl->parent());
2563 assert(dl == blk->loop(), "blk->loop() already in innermost list")do { if (!(dl == blk->loop())) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2563, "assert(" "dl == blk->loop()" ") failed", "blk->loop() already in innermost list"
); ::breakpoint(); } } while (0)
;
2564#endif
2565 blk->set_loop(innermost);
2566 }
2567 innermost->def_locals()->add(blk->def_locals());
2568 Loop* l = innermost;
2569 Loop* p = l->parent();
2570 while (p && l->head() == blk) {
2571 l->set_sibling(p->child()); // Put self on parents 'next child'
2572 p->set_child(l); // Make self the first child of parent
2573 p->def_locals()->add(l->def_locals());
2574 l = p; // Walk up the parent chain
2575 p = l->parent();
2576 }
2577 } else {
2578 blk->set_loop(innermost);
2579 innermost->def_locals()->add(blk->def_locals());
2580 }
2581}
2582
2583// ------------------------------------------------------------------
2584// ciTypeFlow::Loop::contains
2585//
2586// Returns true if lp is nested loop.
2587bool ciTypeFlow::Loop::contains(ciTypeFlow::Loop* lp) const {
2588 assert(lp != NULL, "")do { if (!(lp != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2588, "assert(" "lp != __null" ") failed", ""); ::breakpoint
(); } } while (0)
;
2589 if (this == lp || head() == lp->head()) return true;
2590 int depth1 = depth();
2591 int depth2 = lp->depth();
2592 if (depth1 > depth2)
2593 return false;
2594 while (depth1 < depth2) {
2595 depth2--;
2596 lp = lp->parent();
2597 }
2598 return this == lp;
2599}
2600
2601// ------------------------------------------------------------------
2602// ciTypeFlow::Loop::depth
2603//
2604// Loop depth
2605int ciTypeFlow::Loop::depth() const {
2606 int dp = 0;
2607 for (Loop* lp = this->parent(); lp != NULL__null; lp = lp->parent())
2608 dp++;
2609 return dp;
2610}
2611
2612#ifndef PRODUCT
2613// ------------------------------------------------------------------
2614// ciTypeFlow::Loop::print
2615void ciTypeFlow::Loop::print(outputStream* st, int indent) const {
2616 for (int i = 0; i < indent; i++) st->print(" ");
2617 st->print("%d<-%d %s",
2618 is_root() ? 0 : this->head()->pre_order(),
2619 is_root() ? 0 : this->tail()->pre_order(),
2620 is_irreducible()?" irr":"");
2621 st->print(" defs: ");
2622 def_locals()->print_on(st, _head->outer()->method()->max_locals());
2623 st->cr();
2624 for (Loop* ch = child(); ch != NULL__null; ch = ch->sibling())
2625 ch->print(st, indent+2);
2626}
2627#endif
2628
2629// ------------------------------------------------------------------
2630// ciTypeFlow::df_flow_types
2631//
2632// Perform the depth first type flow analysis. Helper for flow_types.
2633void ciTypeFlow::df_flow_types(Block* start,
2634 bool do_flow,
2635 StateVector* temp_vector,
2636 JsrSet* temp_set) {
2637 int dft_len = 100;
2638 GrowableArray<Block*> stk(dft_len);
2639
2640 ciBlock* dummy = _method->get_method_blocks()->make_dummy_block();
2641 JsrSet* root_set = new JsrSet(0);
2642 Block* root_head = new (arena()) Block(this, dummy, root_set);
2643 Block* root_tail = new (arena()) Block(this, dummy, root_set);
2644 root_head->set_pre_order(0);
2645 root_head->set_post_order(0);
2646 root_tail->set_pre_order(max_jint);
2647 root_tail->set_post_order(max_jint);
2648 set_loop_tree_root(new (arena()) Loop(root_head, root_tail));
2649
2650 stk.push(start);
2651
2652 _next_pre_order = 0; // initialize pre_order counter
2653 _rpo_list = NULL__null;
2654 int next_po = 0; // initialize post_order counter
2655
2656 // Compute RPO and the control flow graph
2657 int size;
2658 while ((size = stk.length()) > 0) {
2659 Block* blk = stk.top(); // Leave node on stack
2660 if (!blk->is_visited()) {
2661 // forward arc in graph
2662 assert (!blk->has_pre_order(), "")do { if (!(!blk->has_pre_order())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2662, "assert(" "!blk->has_pre_order()" ") failed", "");
::breakpoint(); } } while (0)
;
2663 blk->set_next_pre_order();
2664
2665 if (_next_pre_order >= (int)Compile::current()->max_node_limit() / 2) {
2666 // Too many basic blocks. Bail out.
2667 // This can happen when try/finally constructs are nested to depth N,
2668 // and there is O(2**N) cloning of jsr bodies. See bug 4697245!
2669 // "MaxNodeLimit / 2" is used because probably the parser will
2670 // generate at least twice that many nodes and bail out.
2671 record_failure("too many basic blocks");
2672 return;
2673 }
2674 if (do_flow) {
2675 flow_block(blk, temp_vector, temp_set);
2676 if (failing()) return; // Watch for bailouts.
2677 }
2678 } else if (!blk->is_post_visited()) {
2679 // cross or back arc
2680 for (SuccIter iter(blk); !iter.done(); iter.next()) {
2681 Block* succ = iter.succ();
2682 if (!succ->is_visited()) {
2683 stk.push(succ);
2684 }
2685 }
2686 if (stk.length() == size) {
2687 // There were no additional children, post visit node now
2688 stk.pop(); // Remove node from stack
2689
2690 build_loop_tree(blk);
2691 blk->set_post_order(next_po++); // Assign post order
2692 prepend_to_rpo_list(blk);
2693 assert(blk->is_post_visited(), "")do { if (!(blk->is_post_visited())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2693, "assert(" "blk->is_post_visited()" ") failed", "")
; ::breakpoint(); } } while (0)
;
2694
2695 if (blk->is_loop_head() && !blk->is_on_work_list()) {
2696 // Assume loop heads need more data flow
2697 add_to_work_list(blk);
2698 }
2699 }
2700 } else {
2701 stk.pop(); // Remove post-visited node from stack
2702 }
2703 }
2704}
2705
2706// ------------------------------------------------------------------
2707// ciTypeFlow::flow_types
2708//
2709// Perform the type flow analysis, creating and cloning Blocks as
2710// necessary.
2711void ciTypeFlow::flow_types() {
2712 ResourceMark rm;
2713 StateVector* temp_vector = new StateVector(this);
2714 JsrSet* temp_set = new JsrSet(4);
2715
2716 // Create the method entry block.
2717 Block* start = block_at(start_bci(), temp_set);
2718
2719 // Load the initial state into it.
2720 const StateVector* start_state = get_start_state();
2721 if (failing()) return;
2722 start->meet(start_state);
2723
2724 // Depth first visit
2725 df_flow_types(start, true /*do flow*/, temp_vector, temp_set);
2726
2727 if (failing()) return;
2728 assert(_rpo_list == start, "must be start")do { if (!(_rpo_list == start)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2728, "assert(" "_rpo_list == start" ") failed", "must be start"
); ::breakpoint(); } } while (0)
;
2729
2730 // Any loops found?
2731 if (loop_tree_root()->child() != NULL__null &&
2732 env()->comp_level() >= CompLevel_full_optimization) {
2733 // Loop optimizations are not performed on Tier1 compiles.
2734
2735 bool changed = clone_loop_heads(loop_tree_root(), temp_vector, temp_set);
2736
2737 // If some loop heads were cloned, recompute postorder and loop tree
2738 if (changed) {
2739 loop_tree_root()->set_child(NULL__null);
2740 for (Block* blk = _rpo_list; blk != NULL__null;) {
2741 Block* next = blk->rpo_next();
2742 blk->df_init();
2743 blk = next;
2744 }
2745 df_flow_types(start, false /*no flow*/, temp_vector, temp_set);
2746 }
2747 }
2748
2749 if (CITraceTypeFlow) {
2750 tty->print_cr("\nLoop tree");
2751 loop_tree_root()->print();
2752 }
2753
2754 // Continue flow analysis until fixed point reached
2755
2756 debug_only(int max_block = _next_pre_order;)int max_block = _next_pre_order;
2757
2758 while (!work_list_empty()) {
2759 Block* blk = work_list_next();
2760 assert (blk->has_post_order(), "post order assigned above")do { if (!(blk->has_post_order())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2760, "assert(" "blk->has_post_order()" ") failed", "post order assigned above"
); ::breakpoint(); } } while (0)
;
2761
2762 flow_block(blk, temp_vector, temp_set);
2763
2764 assert (max_block == _next_pre_order, "no new blocks")do { if (!(max_block == _next_pre_order)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2764, "assert(" "max_block == _next_pre_order" ") failed", "no new blocks"
); ::breakpoint(); } } while (0)
;
2765 assert (!failing(), "no more bailouts")do { if (!(!failing())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2765, "assert(" "!failing()" ") failed", "no more bailouts"
); ::breakpoint(); } } while (0)
;
2766 }
2767}
2768
2769// ------------------------------------------------------------------
2770// ciTypeFlow::map_blocks
2771//
2772// Create the block map, which indexes blocks in reverse post-order.
2773void ciTypeFlow::map_blocks() {
2774 assert(_block_map == NULL, "single initialization")do { if (!(_block_map == __null)) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2774, "assert(" "_block_map == __null" ") failed", "single initialization"
); ::breakpoint(); } } while (0)
;
2775 int block_ct = _next_pre_order;
2776 _block_map = NEW_ARENA_ARRAY(arena(), Block*, block_ct)(Block**) (arena())->Amalloc((block_ct) * sizeof(Block*));
2777 assert(block_ct == block_count(), "")do { if (!(block_ct == block_count())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2777, "assert(" "block_ct == block_count()" ") failed", "")
; ::breakpoint(); } } while (0)
;
2778
2779 Block* blk = _rpo_list;
2780 for (int m = 0; m < block_ct; m++) {
2781 int rpo = blk->rpo();
2782 assert(rpo == m, "should be sequential")do { if (!(rpo == m)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2782, "assert(" "rpo == m" ") failed", "should be sequential"
); ::breakpoint(); } } while (0)
;
2783 _block_map[rpo] = blk;
2784 blk = blk->rpo_next();
2785 }
2786 assert(blk == NULL, "should be done")do { if (!(blk == __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2786, "assert(" "blk == __null" ") failed", "should be done"
); ::breakpoint(); } } while (0)
;
2787
2788 for (int j = 0; j < block_ct; j++) {
2789 assert(_block_map[j] != NULL, "must not drop any blocks")do { if (!(_block_map[j] != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2789, "assert(" "_block_map[j] != __null" ") failed", "must not drop any blocks"
); ::breakpoint(); } } while (0)
;
2790 Block* block = _block_map[j];
2791 // Remove dead blocks from successor lists:
2792 for (int e = 0; e <= 1; e++) {
2793 GrowableArray<Block*>* l = e? block->exceptions(): block->successors();
2794 for (int k = 0; k < l->length(); k++) {
2795 Block* s = l->at(k);
2796 if (!s->has_post_order()) {
2797 if (CITraceTypeFlow) {
2798 tty->print("Removing dead %s successor of #%d: ", (e? "exceptional": "normal"), block->pre_order());
2799 s->print_value_on(tty);
2800 tty->cr();
2801 }
2802 l->remove(s);
2803 --k;
2804 }
2805 }
2806 }
2807 }
2808}
2809
2810// ------------------------------------------------------------------
2811// ciTypeFlow::get_block_for
2812//
2813// Find a block with this ciBlock which has a compatible JsrSet.
2814// If no such block exists, create it, unless the option is no_create.
2815// If the option is create_backedge_copy, always create a fresh backedge copy.
2816ciTypeFlow::Block* ciTypeFlow::get_block_for(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs, CreateOption option) {
2817 Arena* a = arena();
2818 GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex];
2819 if (blocks == NULL__null) {
2820 // Query only?
2821 if (option == no_create) return NULL__null;
2822
2823 // Allocate the growable array.
2824 blocks = new (a) GrowableArray<Block*>(a, 4, 0, NULL__null);
2825 _idx_to_blocklist[ciBlockIndex] = blocks;
2826 }
2827
2828 if (option != create_backedge_copy) {
2829 int len = blocks->length();
2830 for (int i = 0; i < len; i++) {
2831 Block* block = blocks->at(i);
2832 if (!block->is_backedge_copy() && block->is_compatible_with(jsrs)) {
2833 return block;
2834 }
2835 }
2836 }
2837
2838 // Query only?
2839 if (option == no_create) return NULL__null;
2840
2841 // We did not find a compatible block. Create one.
2842 Block* new_block = new (a) Block(this, _method->get_method_blocks()->block(ciBlockIndex), jsrs);
2843 if (option == create_backedge_copy) new_block->set_backedge_copy(true);
2844 blocks->append(new_block);
2845 return new_block;
2846}
2847
2848// ------------------------------------------------------------------
2849// ciTypeFlow::backedge_copy_count
2850//
2851int ciTypeFlow::backedge_copy_count(int ciBlockIndex, ciTypeFlow::JsrSet* jsrs) const {
2852 GrowableArray<Block*>* blocks = _idx_to_blocklist[ciBlockIndex];
2853
2854 if (blocks == NULL__null) {
2855 return 0;
2856 }
2857
2858 int count = 0;
2859 int len = blocks->length();
2860 for (int i = 0; i < len; i++) {
2861 Block* block = blocks->at(i);
2862 if (block->is_backedge_copy() && block->is_compatible_with(jsrs)) {
2863 count++;
2864 }
2865 }
2866
2867 return count;
2868}
2869
2870// ------------------------------------------------------------------
2871// ciTypeFlow::do_flow
2872//
2873// Perform type inference flow analysis.
2874void ciTypeFlow::do_flow() {
2875 if (CITraceTypeFlow) {
2876 tty->print_cr("\nPerforming flow analysis on method");
2877 method()->print();
2878 if (is_osr_flow()) tty->print(" at OSR bci %d", start_bci());
2879 tty->cr();
2880 method()->print_codes();
2881 }
2882 if (CITraceTypeFlow) {
2883 tty->print_cr("Initial CI Blocks");
2884 print_on(tty);
2885 }
2886 flow_types();
2887 // Watch for bailouts.
2888 if (failing()) {
2889 return;
2890 }
2891
2892 map_blocks();
2893
2894 if (CIPrintTypeFlow || CITraceTypeFlow) {
2895 rpo_print_on(tty);
2896 }
2897}
2898
2899// ------------------------------------------------------------------
2900// ciTypeFlow::is_dominated_by
2901//
2902// Determine if the instruction at bci is dominated by the instruction at dom_bci.
2903bool ciTypeFlow::is_dominated_by(int bci, int dom_bci) {
2904 assert(!method()->has_jsrs(), "jsrs are not supported")do { if (!(!method()->has_jsrs())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/ci/ciTypeFlow.cpp"
, 2904, "assert(" "!method()->has_jsrs()" ") failed", "jsrs are not supported"
); ::breakpoint(); } } while (0)
;
2905
2906 ResourceMark rm;
2907 JsrSet* jsrs = new ciTypeFlow::JsrSet();
2908 int index = _method->get_method_blocks()->block_containing(bci)->index();
2909 int dom_index = _method->get_method_blocks()->block_containing(dom_bci)->index();
2910 Block* block = get_block_for(index, jsrs, ciTypeFlow::no_create);
2911 Block* dom_block = get_block_for(dom_index, jsrs, ciTypeFlow::no_create);
2912
2913 // Start block dominates all other blocks
2914 if (start_block()->rpo() == dom_block->rpo()) {
2915 return true;
2916 }
2917
2918 // Dominated[i] is true if block i is dominated by dom_block
2919 int num_blocks = block_count();
2920 bool* dominated = NEW_RESOURCE_ARRAY(bool, num_blocks)(bool*) resource_allocate_bytes((num_blocks) * sizeof(bool));
2921 for (int i = 0; i < num_blocks; ++i) {
2922 dominated[i] = true;
2923 }
2924 dominated[start_block()->rpo()] = false;
2925
2926 // Iterative dominator algorithm
2927 bool changed = true;
2928 while (changed) {
2929 changed = false;
2930 // Use reverse postorder iteration
2931 for (Block* blk = _rpo_list; blk != NULL__null; blk = blk->rpo_next()) {
2932 if (blk->is_start()) {
2933 // Ignore start block
2934 continue;
2935 }
2936 // The block is dominated if it is the dominating block
2937 // itself or if all predecessors are dominated.
2938 int index = blk->rpo();
2939 bool dom = (index == dom_block->rpo());
2940 if (!dom) {
2941 // Check if all predecessors are dominated
2942 dom = true;
2943 for (int i = 0; i < blk->predecessors()->length(); ++i) {
2944 Block* pred = blk->predecessors()->at(i);
2945 if (!dominated[pred->rpo()]) {
2946 dom = false;
2947 break;
2948 }
2949 }
2950 }
2951 // Update dominator information
2952 if (dominated[index] != dom) {
2953 changed = true;
2954 dominated[index] = dom;
2955 }
2956 }
2957 }
2958 // block dominated by dom_block?
2959 return dominated[block->rpo()];
2960}
2961
2962// ------------------------------------------------------------------
2963// ciTypeFlow::record_failure()
2964// The ciTypeFlow object keeps track of failure reasons separately from the ciEnv.
2965// This is required because there is not a 1-1 relation between the ciEnv and
2966// the TypeFlow passes within a compilation task. For example, if the compiler
2967// is considering inlining a method, it will request a TypeFlow. If that fails,
2968// the compilation as a whole may continue without the inlining. Some TypeFlow
2969// requests are not optional; if they fail the requestor is responsible for
2970// copying the failure reason up to the ciEnv. (See Parse::Parse.)
2971void ciTypeFlow::record_failure(const char* reason) {
2972 if (env()->log() != NULL__null) {
2973 env()->log()->elem("failure reason='%s' phase='typeflow'", reason);
2974 }
2975 if (_failure_reason == NULL__null) {
2976 // Record the first failure reason.
2977 _failure_reason = reason;
2978 }
2979}
2980
2981#ifndef PRODUCT
2982// ------------------------------------------------------------------
2983// ciTypeFlow::print_on
2984void ciTypeFlow::print_on(outputStream* st) const {
2985 // Walk through CI blocks
2986 st->print_cr("********************************************************");
2987 st->print ("TypeFlow for ");
2988 method()->name()->print_symbol_on(st);
2989 int limit_bci = code_size();
2990 st->print_cr(" %d bytes", limit_bci);
2991 ciMethodBlocks* mblks = _method->get_method_blocks();
2992 ciBlock* current = NULL__null;
2993 for (int bci = 0; bci < limit_bci; bci++) {
2994 ciBlock* blk = mblks->block_containing(bci);
2995 if (blk != NULL__null && blk != current) {
2996 current = blk;
2997 current->print_on(st);
2998
2999 GrowableArray<Block*>* blocks = _idx_to_blocklist[blk->index()];
3000 int num_blocks = (blocks == NULL__null) ? 0 : blocks->length();
3001
3002 if (num_blocks == 0) {
3003 st->print_cr(" No Blocks");
3004 } else {
3005 for (int i = 0; i < num_blocks; i++) {
3006 Block* block = blocks->at(i);
3007 block->print_on(st);
3008 }
3009 }
3010 st->print_cr("--------------------------------------------------------");
3011 st->cr();
3012 }
3013 }
3014 st->print_cr("********************************************************");
3015 st->cr();
3016}
3017
3018void ciTypeFlow::rpo_print_on(outputStream* st) const {
3019 st->print_cr("********************************************************");
3020 st->print ("TypeFlow for ");
3021 method()->name()->print_symbol_on(st);
3022 int limit_bci = code_size();
3023 st->print_cr(" %d bytes", limit_bci);
3024 for (Block* blk = _rpo_list; blk != NULL__null; blk = blk->rpo_next()) {
3025 blk->print_on(st);
3026 st->print_cr("--------------------------------------------------------");
3027 st->cr();
3028 }
3029 st->print_cr("********************************************************");
3030 st->cr();
3031}
3032#endif