annotate src/share/vm/ci/ciMethodBlocks.cpp @ 8733:9def4075da6d

8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate(). Reviewed-by: johnc, ysr Contributed-by: tamao <tao.mao@oracle.com>
author tamao
date Tue, 05 Mar 2013 15:36:56 -0800
parents 8012aa3ccede
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
2 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
26 #include "ci/ciMethodBlocks.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
27 #include "ci/ciStreams.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
28 #include "interpreter/bytecode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
29 #include "utilities/copy.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // ciMethodBlocks
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 ciBlock *ciMethodBlocks::block_containing(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
36 ciBlock *blk = _bci_to_block[bci];
a61af66fc99e Initial load
duke
parents:
diff changeset
37 return blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 }
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 bool ciMethodBlocks::is_block_start(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 assert(bci >=0 && bci < _code_size, "valid bytecode range");
a61af66fc99e Initial load
duke
parents:
diff changeset
42 ciBlock *b = _bci_to_block[bci];
a61af66fc99e Initial load
duke
parents:
diff changeset
43 assert(b != NULL, "must have block for bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
44 return b->start_bci() == bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // ------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // ciMethodBlocks::split_block_at
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Split the block spanning bci into two separate ranges. The former
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // block becomes the second half and a new range is created for the
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // first half. Returns the range beginning at bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
53 ciBlock *ciMethodBlocks::split_block_at(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 ciBlock *former_block = block_containing(bci);
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
55 ciBlock *new_block = new(_arena) ciBlock(_method, _num_blocks++, former_block->start_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _blocks->append(new_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 assert(former_block != NULL, "must not be NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
58 new_block->set_limit_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
59 former_block->set_start_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
60 for (int pos=bci-1; pos >= 0; pos--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 ciBlock *current_block = block_containing(pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if (current_block == former_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Replace it.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _bci_to_block[pos] = new_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 } else if (current_block == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // Non-bytecode start. Skip.
a61af66fc99e Initial load
duke
parents:
diff changeset
67 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // We are done with our backwards walk
a61af66fc99e Initial load
duke
parents:
diff changeset
70 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
26
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
73 // Move an exception handler information if needed.
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
74 if (former_block->is_handler()) {
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
75 int ex_start = former_block->ex_start_bci();
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
76 int ex_end = former_block->ex_limit_bci();
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
77 new_block->set_exception_range(ex_start, ex_end);
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
78 // Clear information in former_block.
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
79 former_block->clear_exception_handler();
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
80 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
81 return former_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 ciBlock *ciMethodBlocks::make_block_at(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 ciBlock *cb = block_containing(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (cb == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // This is our first time visiting this bytecode. Create
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // a fresh block and assign it this starting point.
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
89 ciBlock *nb = new(_arena) ciBlock(_method, _num_blocks++, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
90 _blocks->append(nb);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 _bci_to_block[bci] = nb;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return nb;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 } else if (cb->start_bci() == bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // The block begins at bci. Simply return it.
a61af66fc99e Initial load
duke
parents:
diff changeset
95 return cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // We have already created a block containing bci but
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // not starting at bci. This existing block needs to
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // be split into two.
a61af66fc99e Initial load
duke
parents:
diff changeset
100 return split_block_at(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
104 ciBlock *ciMethodBlocks::make_dummy_block() {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
105 ciBlock *dum = new(_arena) ciBlock(_method, -1, 0);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
106 return dum;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
107 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
108
0
a61af66fc99e Initial load
duke
parents:
diff changeset
109 void ciMethodBlocks::do_analysis() {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 ciBytecodeStream s(_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 ciBlock *cur_block = block_containing(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 int limit_bci = _method->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 while (s.next() != ciBytecodeStream::EOBC()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 int bci = s.cur_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Determine if a new block has been made at the current bci. If
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // this block differs from our current range, switch to the new
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // one and end the old one.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 assert(cur_block != NULL, "must always have a current block");
a61af66fc99e Initial load
duke
parents:
diff changeset
120 ciBlock *new_block = block_containing(bci);
26
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
121 if (new_block == NULL || new_block == cur_block) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // We have not marked this bci as the start of a new block.
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // Keep interpreting the current_range.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 _bci_to_block[bci] = cur_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
125 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 cur_block->set_limit_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 cur_block = new_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 switch (s.cur_bc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 case Bytecodes::_ifeq :
a61af66fc99e Initial load
duke
parents:
diff changeset
132 case Bytecodes::_ifne :
a61af66fc99e Initial load
duke
parents:
diff changeset
133 case Bytecodes::_iflt :
a61af66fc99e Initial load
duke
parents:
diff changeset
134 case Bytecodes::_ifge :
a61af66fc99e Initial load
duke
parents:
diff changeset
135 case Bytecodes::_ifgt :
a61af66fc99e Initial load
duke
parents:
diff changeset
136 case Bytecodes::_ifle :
a61af66fc99e Initial load
duke
parents:
diff changeset
137 case Bytecodes::_if_icmpeq :
a61af66fc99e Initial load
duke
parents:
diff changeset
138 case Bytecodes::_if_icmpne :
a61af66fc99e Initial load
duke
parents:
diff changeset
139 case Bytecodes::_if_icmplt :
a61af66fc99e Initial load
duke
parents:
diff changeset
140 case Bytecodes::_if_icmpge :
a61af66fc99e Initial load
duke
parents:
diff changeset
141 case Bytecodes::_if_icmpgt :
a61af66fc99e Initial load
duke
parents:
diff changeset
142 case Bytecodes::_if_icmple :
a61af66fc99e Initial load
duke
parents:
diff changeset
143 case Bytecodes::_if_acmpeq :
a61af66fc99e Initial load
duke
parents:
diff changeset
144 case Bytecodes::_if_acmpne :
a61af66fc99e Initial load
duke
parents:
diff changeset
145 case Bytecodes::_ifnull :
a61af66fc99e Initial load
duke
parents:
diff changeset
146 case Bytecodes::_ifnonnull :
a61af66fc99e Initial load
duke
parents:
diff changeset
147 {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 cur_block->set_control_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 ciBlock *fall_through = make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
150 int dest_bci = s.get_dest();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 ciBlock *dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 case Bytecodes::_goto :
a61af66fc99e Initial load
duke
parents:
diff changeset
156 {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 cur_block->set_control_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 if (s.next_bci() < limit_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 (void) make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 int dest_bci = s.get_dest();
a61af66fc99e Initial load
duke
parents:
diff changeset
162 ciBlock *dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 case Bytecodes::_jsr :
a61af66fc99e Initial load
duke
parents:
diff changeset
167 {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 cur_block->set_control_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 ciBlock *ret = make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
170 int dest_bci = s.get_dest();
a61af66fc99e Initial load
duke
parents:
diff changeset
171 ciBlock *dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 case Bytecodes::_tableswitch :
a61af66fc99e Initial load
duke
parents:
diff changeset
176 {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 cur_block->set_control_bci(bci);
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
178 Bytecode_tableswitch sw(&s);
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
179 int len = sw.length();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
180 ciBlock *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 int dest_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 for (int i = 0; i < len; i++) {
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
183 dest_bci = s.cur_bci() + sw.dest_offset_at(i);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
184 dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
186 dest_bci = s.cur_bci() + sw.default_offset();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
187 make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if (s.next_bci() < limit_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 dest = make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
192 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 case Bytecodes::_lookupswitch:
a61af66fc99e Initial load
duke
parents:
diff changeset
195 {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 cur_block->set_control_bci(bci);
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
197 Bytecode_lookupswitch sw(&s);
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
198 int len = sw.number_of_pairs();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 ciBlock *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 int dest_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 for (int i = 0; i < len; i++) {
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
202 dest_bci = s.cur_bci() + sw.pair_at(i).offset();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
203 dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 1972
diff changeset
205 dest_bci = s.cur_bci() + sw.default_offset();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
206 dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (s.next_bci() < limit_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 dest = make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 case Bytecodes::_goto_w :
a61af66fc99e Initial load
duke
parents:
diff changeset
214 {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 cur_block->set_control_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 if (s.next_bci() < limit_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 (void) make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 int dest_bci = s.get_far_dest();
a61af66fc99e Initial load
duke
parents:
diff changeset
220 ciBlock *dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 case Bytecodes::_jsr_w :
a61af66fc99e Initial load
duke
parents:
diff changeset
225 {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 cur_block->set_control_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
227 ciBlock *ret = make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
228 int dest_bci = s.get_far_dest();
a61af66fc99e Initial load
duke
parents:
diff changeset
229 ciBlock *dest = make_block_at(dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 case Bytecodes::_athrow :
a61af66fc99e Initial load
duke
parents:
diff changeset
234 cur_block->set_may_throw();
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // fall-through
a61af66fc99e Initial load
duke
parents:
diff changeset
236 case Bytecodes::_ret :
a61af66fc99e Initial load
duke
parents:
diff changeset
237 case Bytecodes::_ireturn :
a61af66fc99e Initial load
duke
parents:
diff changeset
238 case Bytecodes::_lreturn :
a61af66fc99e Initial load
duke
parents:
diff changeset
239 case Bytecodes::_freturn :
a61af66fc99e Initial load
duke
parents:
diff changeset
240 case Bytecodes::_dreturn :
a61af66fc99e Initial load
duke
parents:
diff changeset
241 case Bytecodes::_areturn :
a61af66fc99e Initial load
duke
parents:
diff changeset
242 case Bytecodes::_return :
a61af66fc99e Initial load
duke
parents:
diff changeset
243 cur_block->set_control_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if (s.next_bci() < limit_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 (void) make_block_at(s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // End the last block
a61af66fc99e Initial load
duke
parents:
diff changeset
251 cur_block->set_limit_bci(limit_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 ciMethodBlocks::ciMethodBlocks(Arena *arena, ciMethod *meth): _method(meth),
a61af66fc99e Initial load
duke
parents:
diff changeset
255 _arena(arena), _num_blocks(0), _code_size(meth->code_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 int block_estimate = _code_size / 8;
a61af66fc99e Initial load
duke
parents:
diff changeset
257
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
258 _blocks = new(_arena) GrowableArray<ciBlock *>(_arena, block_estimate, 0, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
259 int b2bsize = _code_size * sizeof(ciBlock **);
a61af66fc99e Initial load
duke
parents:
diff changeset
260 _bci_to_block = (ciBlock **) arena->Amalloc(b2bsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
261 Copy::zero_to_words((HeapWord*) _bci_to_block, b2bsize / sizeof(HeapWord));
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // create initial block covering the entire method
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
264 ciBlock *b = new(arena) ciBlock(_method, _num_blocks++, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
265 _blocks->append(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 _bci_to_block[0] = b;
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // create blocks for exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
269 if (meth->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 ciExceptionHandler* handler = str.handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
272 ciBlock *eb = make_block_at(handler->handler_bci());
26
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
273 //
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
274 // Several exception handlers can have the same handler_bci:
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
275 //
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
276 // try {
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
277 // if (a.foo(b) < 0) {
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
278 // return a.error();
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
279 // }
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
280 // return CoderResult.UNDERFLOW;
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
281 // } finally {
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
282 // a.position(b);
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
283 // }
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
284 //
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
285 // The try block above is divided into 2 exception blocks
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
286 // separated by 'areturn' bci.
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
287 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
288 int ex_start = handler->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 int ex_end = handler->limit();
646
039a914095f4 6772368: REGRESSION:tomcat crashed twice with JDK 7
kvn
parents: 367
diff changeset
290 // ensure a block at the start of exception range and start of following code
039a914095f4 6772368: REGRESSION:tomcat crashed twice with JDK 7
kvn
parents: 367
diff changeset
291 (void) make_block_at(ex_start);
039a914095f4 6772368: REGRESSION:tomcat crashed twice with JDK 7
kvn
parents: 367
diff changeset
292 if (ex_end < _code_size)
039a914095f4 6772368: REGRESSION:tomcat crashed twice with JDK 7
kvn
parents: 367
diff changeset
293 (void) make_block_at(ex_end);
039a914095f4 6772368: REGRESSION:tomcat crashed twice with JDK 7
kvn
parents: 367
diff changeset
294
26
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
295 if (eb->is_handler()) {
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
296 // Extend old handler exception range to cover additional range.
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
297 int old_ex_start = eb->ex_start_bci();
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
298 int old_ex_end = eb->ex_limit_bci();
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
299 if (ex_start > old_ex_start)
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
300 ex_start = old_ex_start;
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
301 if (ex_end < old_ex_end)
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
302 ex_end = old_ex_end;
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
303 eb->clear_exception_handler(); // Reset exception information
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
304 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
305 eb->set_exception_range(ex_start, ex_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // scan the bytecodes and identify blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
310 do_analysis();
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // mark blocks that have exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (meth->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 ciExceptionHandler* handler = str.handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
316 int ex_start = handler->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
317 int ex_end = handler->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 int bci = ex_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 while (bci < ex_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 ciBlock *b = block_containing(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 b->set_has_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
323 bci = b->limit_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 void ciMethodBlocks::clear_processed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 for (int i = 0; i < _blocks->length(); i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
331 _blocks->at(i)->clear_processed();
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
335 void ciMethodBlocks::dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 tty->print("---- blocks for method: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
337 _method->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
338 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 for (int i = 0; i < _blocks->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 tty->print(" B%d: ", i); _blocks->at(i)->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 250
diff changeset
346 ciBlock::ciBlock(ciMethod *method, int index, int start_bci) :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
347 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
348 _method(method),
a61af66fc99e Initial load
duke
parents:
diff changeset
349 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
350 _idx(index), _flags(0), _start_bci(start_bci), _limit_bci(-1), _control_bci(fall_through_bci),
a61af66fc99e Initial load
duke
parents:
diff changeset
351 _ex_start_bci(-1), _ex_limit_bci(-1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 void ciBlock::set_exception_range(int start_bci, int limit_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 assert(limit_bci >= start_bci, "valid range");
26
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
356 assert(!is_handler() && _ex_start_bci == -1 && _ex_limit_bci == -1, "must not be handler");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
357 _ex_start_bci = start_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
358 _ex_limit_bci = limit_bci;
26
0871d5cd64cd 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler
kvn
parents: 0
diff changeset
359 set_handler();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 #ifndef PRODUCT
250
6ca61c728c2d 6712835: Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
never
parents: 196
diff changeset
363 static const char *flagnames[] = {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
364 "Processed",
a61af66fc99e Initial load
duke
parents:
diff changeset
365 "Handler",
a61af66fc99e Initial load
duke
parents:
diff changeset
366 "MayThrow",
a61af66fc99e Initial load
duke
parents:
diff changeset
367 "Jsr",
a61af66fc99e Initial load
duke
parents:
diff changeset
368 "Ret",
a61af66fc99e Initial load
duke
parents:
diff changeset
369 "RetTarget",
a61af66fc99e Initial load
duke
parents:
diff changeset
370 "HasHandler",
a61af66fc99e Initial load
duke
parents:
diff changeset
371 };
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 void ciBlock::dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 tty->print(" [%d .. %d), {", _start_bci, _limit_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 for (int i = 0; i < 8; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 if ((_flags & (1 << i)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 tty->print(" %s", flagnames[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380 tty->print(" ]");
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (is_handler())
a61af66fc99e Initial load
duke
parents:
diff changeset
382 tty->print(" handles(%d..%d)", _ex_start_bci, _ex_limit_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // ------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // ciBlock::print_on
a61af66fc99e Initial load
duke
parents:
diff changeset
388 void ciBlock::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 st->print_cr("--------------------------------------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
390 st->print ("ciBlock [%d - %d) control : ", start_bci(), limit_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
391 if (control_bci() == fall_through_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 st->print_cr("%d:fall through", limit_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
393 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 st->print_cr("%d:%s", control_bci(),
a61af66fc99e Initial load
duke
parents:
diff changeset
395 Bytecodes::name(method()->java_code_at_bci(control_bci())));
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 if (Verbose || WizardMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 method()->print_codes_on(start_bci(), limit_bci(), st);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 #endif