annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 2007:5ddfcf4b079e

7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation. Reviewed-by: kvn, never
author iveresov
date Thu, 02 Dec 2010 17:21:12 -0800
parents ac637b7220d1
children 8012aa3ccede 403dc4c1d7f5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1540
diff changeset
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1540
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1540
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: 1540
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: 1825
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
26 #include "c1/c1_CFGPrinter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
27 #include "c1/c1_Canonicalizer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
28 #include "c1/c1_Compilation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
29 #include "c1/c1_GraphBuilder.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
30 #include "c1/c1_InstructionPrinter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
31 #include "ci/ciField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
32 #include "ci/ciKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
33 #include "interpreter/bytecode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
34 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1825
diff changeset
35 #include "utilities/bitMap.inline.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 class BlockListBuilder VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
38 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
39 Compilation* _compilation;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 IRScope* _scope;
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 BlockList _blocks; // internal list of all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
43 BlockList* _bci2block; // mapping from bci to blocks for GraphBuilder
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // fields used by mark_loops
a61af66fc99e Initial load
duke
parents:
diff changeset
46 BitMap _active; // for iteration of control flow graph
a61af66fc99e Initial load
duke
parents:
diff changeset
47 BitMap _visited; // for iteration of control flow graph
a61af66fc99e Initial load
duke
parents:
diff changeset
48 intArray _loop_map; // caches the information if a block is contained in a loop
a61af66fc99e Initial load
duke
parents:
diff changeset
49 int _next_loop_index; // next free loop number
a61af66fc99e Initial load
duke
parents:
diff changeset
50 int _next_block_number; // for reverse postorder numbering of blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
53 Compilation* compilation() const { return _compilation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
54 IRScope* scope() const { return _scope; }
a61af66fc99e Initial load
duke
parents:
diff changeset
55 ciMethod* method() const { return scope()->method(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
56 XHandlers* xhandlers() const { return scope()->xhandlers(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // unified bailout support
a61af66fc99e Initial load
duke
parents:
diff changeset
59 void bailout(const char* msg) const { compilation()->bailout(msg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 bool bailed_out() const { return compilation()->bailed_out(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // helper functions
a61af66fc99e Initial load
duke
parents:
diff changeset
63 BlockBegin* make_block_at(int bci, BlockBegin* predecessor);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 void handle_exceptions(BlockBegin* current, int cur_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
65 void handle_jsr(BlockBegin* current, int sr_bci, int next_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 void store_one(BlockBegin* current, int local);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 void store_two(BlockBegin* current, int local);
a61af66fc99e Initial load
duke
parents:
diff changeset
68 void set_entries(int osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 void set_leaders();
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 void make_loop_header(BlockBegin* block);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 void mark_loops();
a61af66fc99e Initial load
duke
parents:
diff changeset
73 int mark_loops(BlockBegin* b, bool in_subroutine);
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
76 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // creation
a61af66fc99e Initial load
duke
parents:
diff changeset
82 BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // accessors for GraphBuilder
a61af66fc99e Initial load
duke
parents:
diff changeset
85 BlockList* bci2block() const { return _bci2block; }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 };
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // Implementation of BlockListBuilder
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
92 : _compilation(compilation)
a61af66fc99e Initial load
duke
parents:
diff changeset
93 , _scope(scope)
a61af66fc99e Initial load
duke
parents:
diff changeset
94 , _blocks(16)
a61af66fc99e Initial load
duke
parents:
diff changeset
95 , _bci2block(new BlockList(scope->method()->code_size(), NULL))
a61af66fc99e Initial load
duke
parents:
diff changeset
96 , _next_block_number(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
97 , _active() // size not known yet
a61af66fc99e Initial load
duke
parents:
diff changeset
98 , _visited() // size not known yet
a61af66fc99e Initial load
duke
parents:
diff changeset
99 , _next_loop_index(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
100 , _loop_map() // size not known yet
a61af66fc99e Initial load
duke
parents:
diff changeset
101 {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 set_entries(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 set_leaders();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 mark_loops();
a61af66fc99e Initial load
duke
parents:
diff changeset
107 NOT_PRODUCT(if (PrintInitialBlockList) print());
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (PrintCFGToFile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 stringStream title;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 title.print("BlockListBuilder ");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 scope->method()->print_name(&title);
a61af66fc99e Initial load
duke
parents:
diff changeset
114 CFGPrinter::print_cfg(_bci2block, title.as_string(), false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 void BlockListBuilder::set_entries(int osr_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // generate start blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
122 BlockBegin* std_entry = make_block_at(0, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (scope()->caller() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 std_entry->set(BlockBegin::std_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 if (osr_bci != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 BlockBegin* osr_entry = make_block_at(osr_bci, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 osr_entry->set(BlockBegin::osr_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // generate exception entry blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
132 XHandlers* list = xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
133 const int n = list->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
134 for (int i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 XHandler* h = list->handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 BlockBegin* entry = make_block_at(h->handler_bci(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 entry->set(BlockBegin::exception_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
138 h->set_entry_block(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 assert(method()->bci_block_start().at(cur_bci), "wrong block starts of MethodLivenessAnalyzer");
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 BlockBegin* block = _bci2block->at(cur_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (block == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 block = new BlockBegin(cur_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 block->init_stores_to_locals(method()->max_locals());
a61af66fc99e Initial load
duke
parents:
diff changeset
150 _bci2block->at_put(cur_bci, block);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 _blocks.append(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 assert(predecessor == NULL || predecessor->bci() < cur_bci, "targets for backward branches must already exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 if (predecessor != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 if (block->is_set(BlockBegin::exception_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 BAILOUT_("Exception handler can be reached by both normal and exceptional control flow", block);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 predecessor->add_successor(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 block->increment_total_preds();
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return block;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 inline void BlockListBuilder::store_one(BlockBegin* current, int local) {
a61af66fc99e Initial load
duke
parents:
diff changeset
170 current->stores_to_locals().set_bit(local);
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 inline void BlockListBuilder::store_two(BlockBegin* current, int local) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 store_one(current, local);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 store_one(current, local + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 void BlockListBuilder::handle_exceptions(BlockBegin* current, int cur_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Draws edges from a block to its exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
180 XHandlers* list = xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 const int n = list->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 for (int i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 XHandler* h = list->handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (h->covers(cur_bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 BlockBegin* entry = h->entry_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
188 assert(entry != NULL && entry == _bci2block->at(h->handler_bci()), "entry must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
189 assert(entry->is_set(BlockBegin::exception_entry_flag), "flag must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // add each exception handler only once
a61af66fc99e Initial load
duke
parents:
diff changeset
192 if (!current->is_successor(entry)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 current->add_successor(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 entry->increment_total_preds();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // stop when reaching catchall
a61af66fc99e Initial load
duke
parents:
diff changeset
198 if (h->catch_type() == 0) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void BlockListBuilder::handle_jsr(BlockBegin* current, int sr_bci, int next_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // start a new block after jsr-bytecode and link this block into cfg
a61af66fc99e Initial load
duke
parents:
diff changeset
205 make_block_at(next_bci, current);
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // start a new block at the subroutine entry at mark it with special flag
a61af66fc99e Initial load
duke
parents:
diff changeset
208 BlockBegin* sr_block = make_block_at(sr_bci, current);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (!sr_block->is_set(BlockBegin::subroutine_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 sr_block->set(BlockBegin::subroutine_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 void BlockListBuilder::set_leaders() {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 bool has_xhandlers = xhandlers()->has_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
217 BlockBegin* current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // The information which bci starts a new block simplifies the analysis
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // Without it, backward branches could jump to a bci where no block was created
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // during bytecode iteration. This would require the creation of a new block at the
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // branch target and a modification of the successor lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 BitMap bci_block_start = method()->bci_block_start();
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 ciBytecodeStream s(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
226 while (s.next() != ciBytecodeStream::EOBC()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 int cur_bci = s.cur_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (bci_block_start.at(cur_bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 current = make_block_at(cur_bci, current);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 assert(current != NULL, "must have current block");
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 if (has_xhandlers && GraphBuilder::can_trap(method(), s.cur_bc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 handle_exceptions(current, cur_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 switch (s.cur_bc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // track stores to local variables for selective creation of phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
240 case Bytecodes::_iinc: store_one(current, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 case Bytecodes::_istore: store_one(current, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 case Bytecodes::_lstore: store_two(current, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
243 case Bytecodes::_fstore: store_one(current, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 case Bytecodes::_dstore: store_two(current, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 case Bytecodes::_astore: store_one(current, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 case Bytecodes::_istore_0: store_one(current, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 case Bytecodes::_istore_1: store_one(current, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 case Bytecodes::_istore_2: store_one(current, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 case Bytecodes::_istore_3: store_one(current, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 case Bytecodes::_lstore_0: store_two(current, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 case Bytecodes::_lstore_1: store_two(current, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 case Bytecodes::_lstore_2: store_two(current, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 case Bytecodes::_lstore_3: store_two(current, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 case Bytecodes::_fstore_0: store_one(current, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 case Bytecodes::_fstore_1: store_one(current, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 case Bytecodes::_fstore_2: store_one(current, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 case Bytecodes::_fstore_3: store_one(current, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 case Bytecodes::_dstore_0: store_two(current, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 case Bytecodes::_dstore_1: store_two(current, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 case Bytecodes::_dstore_2: store_two(current, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 case Bytecodes::_dstore_3: store_two(current, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 case Bytecodes::_astore_0: store_one(current, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 case Bytecodes::_astore_1: store_one(current, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 case Bytecodes::_astore_2: store_one(current, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 case Bytecodes::_astore_3: store_one(current, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // track bytecodes that affect the control flow
a61af66fc99e Initial load
duke
parents:
diff changeset
268 case Bytecodes::_athrow: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
269 case Bytecodes::_ret: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
270 case Bytecodes::_ireturn: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
271 case Bytecodes::_lreturn: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
272 case Bytecodes::_freturn: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
273 case Bytecodes::_dreturn: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
274 case Bytecodes::_areturn: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
275 case Bytecodes::_return:
a61af66fc99e Initial load
duke
parents:
diff changeset
276 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 case Bytecodes::_ifeq: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
280 case Bytecodes::_ifne: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
281 case Bytecodes::_iflt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
282 case Bytecodes::_ifge: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
283 case Bytecodes::_ifgt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
284 case Bytecodes::_ifle: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
285 case Bytecodes::_if_icmpeq: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
286 case Bytecodes::_if_icmpne: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
287 case Bytecodes::_if_icmplt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
288 case Bytecodes::_if_icmpge: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
289 case Bytecodes::_if_icmpgt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
290 case Bytecodes::_if_icmple: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
291 case Bytecodes::_if_acmpeq: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
292 case Bytecodes::_if_acmpne: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
293 case Bytecodes::_ifnull: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
294 case Bytecodes::_ifnonnull:
a61af66fc99e Initial load
duke
parents:
diff changeset
295 make_block_at(s.next_bci(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
296 make_block_at(s.get_dest(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
297 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
298 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 case Bytecodes::_goto:
a61af66fc99e Initial load
duke
parents:
diff changeset
301 make_block_at(s.get_dest(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 case Bytecodes::_goto_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
306 make_block_at(s.get_far_dest(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 case Bytecodes::_jsr:
a61af66fc99e Initial load
duke
parents:
diff changeset
311 handle_jsr(current, s.get_dest(), s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
312 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
313 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 case Bytecodes::_jsr_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
316 handle_jsr(current, s.get_far_dest(), s.next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
317 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 case Bytecodes::_tableswitch: {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // set block for each case
a61af66fc99e Initial load
duke
parents:
diff changeset
322 Bytecode_tableswitch *switch_ = Bytecode_tableswitch_at(s.cur_bcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
323 int l = switch_->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
324 for (int i = 0; i < l; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 make_block_at(cur_bci + switch_->dest_offset_at(i), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 make_block_at(cur_bci + switch_->default_offset(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 case Bytecodes::_lookupswitch: {
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // set block for each case
a61af66fc99e Initial load
duke
parents:
diff changeset
334 Bytecode_lookupswitch *switch_ = Bytecode_lookupswitch_at(s.cur_bcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
335 int l = switch_->number_of_pairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 for (int i = 0; i < l; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 make_block_at(cur_bci + switch_->pair_at(i)->offset(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 make_block_at(cur_bci + switch_->default_offset(), current);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 current = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 void BlockListBuilder::mark_loops() {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 _active = BitMap(BlockBegin::number_of_blocks()); _active.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 _visited = BitMap(BlockBegin::number_of_blocks()); _visited.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
353 _loop_map = intArray(BlockBegin::number_of_blocks(), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 _next_loop_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 _next_block_number = _blocks.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // recursively iterate the control flow graph
a61af66fc99e Initial load
duke
parents:
diff changeset
358 mark_loops(_bci2block->at(0), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 assert(_next_block_number >= 0, "invalid block numbers");
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 void BlockListBuilder::make_loop_header(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 if (block->is_set(BlockBegin::exception_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // exception edges may look like loops but don't mark them as such
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // since it screws up block ordering.
a61af66fc99e Initial load
duke
parents:
diff changeset
366 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 if (!block->is_set(BlockBegin::parser_loop_header_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 block->set(BlockBegin::parser_loop_header_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 assert(_loop_map.at(block->block_id()) == 0, "must not be set yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
372 assert(0 <= _next_loop_index && _next_loop_index < BitsPerInt, "_next_loop_index is used as a bit-index in integer");
a61af66fc99e Initial load
duke
parents:
diff changeset
373 _loop_map.at_put(block->block_id(), 1 << _next_loop_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 if (_next_loop_index < 31) _next_loop_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // block already marked as loop header
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
377 assert(is_power_of_2((unsigned int)_loop_map.at(block->block_id())), "exactly one bit must be set");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 int block_id = block->block_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 if (_visited.at(block_id)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 if (_active.at(block_id)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // reached block via backward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
387 make_loop_header(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // return cached loop information for this block
a61af66fc99e Initial load
duke
parents:
diff changeset
390 return _loop_map.at(block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (block->is_set(BlockBegin::subroutine_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 in_subroutine = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // set active and visited bits before successors are processed
a61af66fc99e Initial load
duke
parents:
diff changeset
398 _visited.set_bit(block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
399 _active.set_bit(block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 intptr_t loop_state = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 for (int i = block->number_of_sux() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // recursively process all successors
a61af66fc99e Initial load
duke
parents:
diff changeset
404 loop_state |= mark_loops(block->sux_at(i), in_subroutine);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // clear active-bit after all successors are processed
a61af66fc99e Initial load
duke
parents:
diff changeset
408 _active.clear_bit(block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // reverse-post-order numbering of all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
411 block->set_depth_first_number(_next_block_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 _next_block_number--;
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (loop_state != 0 || in_subroutine ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // block is contained at least in one loop, so phi functions are necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // phi functions are also necessary for all locals stored in a subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
417 scope()->requires_phi_function().set_union(block->stores_to_locals());
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (block->is_set(BlockBegin::parser_loop_header_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 int header_loop_state = _loop_map.at(block_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 assert(is_power_of_2((unsigned)header_loop_state), "exactly one bit must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // If the highest bit is set (i.e. when integer value is negative), the method
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // has 32 or more loops. This bit is never cleared because it is used for multiple loops
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if (header_loop_state >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 clear_bits(loop_state, header_loop_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // cache and return loop information for this block
a61af66fc99e Initial load
duke
parents:
diff changeset
432 _loop_map.at_put(block_id, loop_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 return loop_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 int compare_depth_first(BlockBegin** a, BlockBegin** b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
440 return (*a)->depth_first_number() - (*b)->depth_first_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 void BlockListBuilder::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 tty->print("----- initial block list of BlockListBuilder for method ");
a61af66fc99e Initial load
duke
parents:
diff changeset
445 method()->print_short_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
446 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // better readability if blocks are sorted in processing order
a61af66fc99e Initial load
duke
parents:
diff changeset
449 _blocks.sort(compare_depth_first);
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 for (int i = 0; i < _blocks.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 BlockBegin* cur = _blocks.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
453 tty->print("%4d: B%-4d bci: %-4d preds: %-4d ", cur->depth_first_number(), cur->block_id(), cur->bci(), cur->total_preds());
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 tty->print(cur->is_set(BlockBegin::std_entry_flag) ? " std" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
456 tty->print(cur->is_set(BlockBegin::osr_entry_flag) ? " osr" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
457 tty->print(cur->is_set(BlockBegin::exception_entry_flag) ? " ex" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
458 tty->print(cur->is_set(BlockBegin::subroutine_entry_flag) ? " sr" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
459 tty->print(cur->is_set(BlockBegin::parser_loop_header_flag) ? " lh" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (cur->number_of_sux() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 tty->print(" sux: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
463 for (int j = 0; j < cur->number_of_sux(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 BlockBegin* sux = cur->sux_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
465 tty->print("B%d ", sux->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
468 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // A simple growable array of Values indexed by ciFields
a61af66fc99e Initial load
duke
parents:
diff changeset
476 class FieldBuffer: public CompilationResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
478 GrowableArray<Value> _values;
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
481 FieldBuffer() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 void kill() {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 _values.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 Value at(ciField* field) {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 assert(field->holder()->is_loaded(), "must be a loaded field");
a61af66fc99e Initial load
duke
parents:
diff changeset
489 int offset = field->offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (offset < _values.length()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 return _values.at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
492 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 void at_put(ciField* field, Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 assert(field->holder()->is_loaded(), "must be a loaded field");
a61af66fc99e Initial load
duke
parents:
diff changeset
499 int offset = field->offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 _values.at_put_grow(offset, value, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 };
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // MemoryBuffer is fairly simple model of the current state of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // It partitions memory into several pieces. The first piece is
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // generic memory where little is known about the owner of the memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // This is conceptually represented by the tuple <O, F, V> which says
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // that the field F of object O has value V. This is flattened so
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // that F is represented by the offset of the field and the parallel
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // arrays _objects and _values are used for O and V. Loads of O.F can
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // simply use V. Newly allocated objects are kept in a separate list
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // along with a parallel array for each object which represents the
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // current value of its fields. Stores of the default value to fields
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // which have never been stored to before are eliminated since they
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // are redundant. Once newly allocated objects are stored into
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // another object or they are passed out of the current compile they
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // are treated like generic memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 class MemoryBuffer: public CompilationResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
522 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
523 FieldBuffer _values;
a61af66fc99e Initial load
duke
parents:
diff changeset
524 GrowableArray<Value> _objects;
a61af66fc99e Initial load
duke
parents:
diff changeset
525 GrowableArray<Value> _newobjects;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 GrowableArray<FieldBuffer*> _fields;
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
529 MemoryBuffer() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 StoreField* store(StoreField* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if (!EliminateFieldAccess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 Value object = st->obj();
a61af66fc99e Initial load
duke
parents:
diff changeset
537 Value value = st->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
538 ciField* field = st->field();
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (field->holder()->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 int offset = field->offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
541 int index = _newobjects.find(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if (index != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // newly allocated object with no other stores performed on this field
a61af66fc99e Initial load
duke
parents:
diff changeset
544 FieldBuffer* buf = _fields.at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if (buf->at(field) == NULL && is_default_value(value)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
547 if (PrintIRDuringConstruction && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 tty->print_cr("Eliminated store for object %d:", index);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 st->print_line();
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
552 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 buf->at_put(field, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 _objects.at_put_grow(offset, object, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 _values.at_put(field, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 store_value(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // if we held onto field names we could alias based on names but
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // we don't know what's being stored to so kill it all.
a61af66fc99e Initial load
duke
parents:
diff changeset
565 kill();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // return true if this value correspond to the default value of a field.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 bool is_default_value(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 Constant* con = value->as_Constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 switch (con->type()->tag()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 case intTag: return con->type()->as_IntConstant()->value() == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
577 case longTag: return con->type()->as_LongConstant()->value() == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
578 case floatTag: return jint_cast(con->type()->as_FloatConstant()->value()) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
579 case doubleTag: return jlong_cast(con->type()->as_DoubleConstant()->value()) == jlong_cast(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 case objectTag: return con->type() == objectNull;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // return either the actual value of a load or the load itself
a61af66fc99e Initial load
duke
parents:
diff changeset
589 Value load(LoadField* load) {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 if (!EliminateFieldAccess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 return load;
a61af66fc99e Initial load
duke
parents:
diff changeset
592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 if (RoundFPResults && UseSSE < 2 && load->type()->is_float_kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // can't skip load since value might get rounded as a side effect
a61af66fc99e Initial load
duke
parents:
diff changeset
596 return load;
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 ciField* field = load->field();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 Value object = load->obj();
a61af66fc99e Initial load
duke
parents:
diff changeset
601 if (field->holder()->is_loaded() && !field->is_volatile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 int offset = field->offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
603 Value result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 int index = _newobjects.find(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if (index != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 result = _fields.at(index)->at(field);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 } else if (_objects.at_grow(offset, NULL) == object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 result = _values.at(field);
a61af66fc99e Initial load
duke
parents:
diff changeset
609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
610 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
612 if (PrintIRDuringConstruction && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 tty->print_cr("Eliminated load: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
614 load->print_line();
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
617 assert(result->type()->tag() == load->type()->tag(), "wrong types");
a61af66fc99e Initial load
duke
parents:
diff changeset
618 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
621 return load;
a61af66fc99e Initial load
duke
parents:
diff changeset
622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Record this newly allocated object
a61af66fc99e Initial load
duke
parents:
diff changeset
625 void new_instance(NewInstance* object) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 int index = _newobjects.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
627 _newobjects.append(object);
a61af66fc99e Initial load
duke
parents:
diff changeset
628 if (_fields.at_grow(index, NULL) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 _fields.at_put(index, new FieldBuffer());
a61af66fc99e Initial load
duke
parents:
diff changeset
630 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 _fields.at(index)->kill();
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 void store_value(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
636 int index = _newobjects.find(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 if (index != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // stored a newly allocated object into another object.
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // Assume we've lost track of it as separate slice of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // We could do better by keeping track of whether individual
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // fields could alias each other.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 _newobjects.remove_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // pull out the field info and store it at the end up the list
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // of field info list to be reused later.
a61af66fc99e Initial load
duke
parents:
diff changeset
645 _fields.append(_fields.at(index));
a61af66fc99e Initial load
duke
parents:
diff changeset
646 _fields.remove_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 void kill() {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 _newobjects.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 _objects.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 _values.kill();
a61af66fc99e Initial load
duke
parents:
diff changeset
654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
655 };
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // Implementation of GraphBuilder's ScopeData
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 GraphBuilder::ScopeData::ScopeData(ScopeData* parent)
a61af66fc99e Initial load
duke
parents:
diff changeset
661 : _parent(parent)
a61af66fc99e Initial load
duke
parents:
diff changeset
662 , _bci2block(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
663 , _scope(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
664 , _has_handler(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
665 , _stream(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
666 , _work_list(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
667 , _parsing_jsr(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
668 , _jsr_xhandlers(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
669 , _caller_stack_size(-1)
a61af66fc99e Initial load
duke
parents:
diff changeset
670 , _continuation(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
671 , _num_returns(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
672 , _cleanup_block(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
673 , _cleanup_return_prev(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
674 , _cleanup_state(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
675 {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 if (parent != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 _max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f);
a61af66fc99e Initial load
duke
parents:
diff changeset
678 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
679 _max_inline_size = MaxInlineSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if (_max_inline_size < MaxTrivialSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 _max_inline_size = MaxTrivialSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 void GraphBuilder::kill_all() {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 if (UseLocalValueNumbering) {
a61af66fc99e Initial load
duke
parents:
diff changeset
689 vmap()->kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
690 }
a61af66fc99e Initial load
duke
parents:
diff changeset
691 _memory->kill();
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 BlockBegin* GraphBuilder::ScopeData::block_at(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 if (parsing_jsr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // It is necessary to clone all blocks associated with a
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // subroutine, including those for exception handlers in the scope
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // of the method containing the jsr (because those exception
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // handlers may contain ret instructions in some cases).
a61af66fc99e Initial load
duke
parents:
diff changeset
701 BlockBegin* block = bci2block()->at(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 if (block != NULL && block == parent()->bci2block()->at(bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
703 BlockBegin* new_block = new BlockBegin(block->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
704 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
705 if (PrintInitialBlockList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
706 tty->print_cr("CFG: cloned block %d (bci %d) as block %d for jsr",
a61af66fc99e Initial load
duke
parents:
diff changeset
707 block->block_id(), block->bci(), new_block->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // copy data from cloned blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
711 new_block->set_depth_first_number(block->depth_first_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if (block->is_set(BlockBegin::parser_loop_header_flag)) new_block->set(BlockBegin::parser_loop_header_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // Preserve certain flags for assertion checking
a61af66fc99e Initial load
duke
parents:
diff changeset
714 if (block->is_set(BlockBegin::subroutine_entry_flag)) new_block->set(BlockBegin::subroutine_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
715 if (block->is_set(BlockBegin::exception_entry_flag)) new_block->set(BlockBegin::exception_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // copy was_visited_flag to allow early detection of bailouts
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // if a block that is used in a jsr has already been visited before,
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // it is shared between the normal control flow and a subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // BlockBegin::try_merge returns false when the flag is set, this leads
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // to a compilation bailout
a61af66fc99e Initial load
duke
parents:
diff changeset
722 if (block->is_set(BlockBegin::was_visited_flag)) new_block->set(BlockBegin::was_visited_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 bci2block()->at_put(bci, new_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 block = new_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727 return block;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 return bci2block()->at(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 XHandlers* GraphBuilder::ScopeData::xhandlers() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (_jsr_xhandlers == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 assert(!parsing_jsr(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
737 return scope()->xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739 assert(parsing_jsr(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
740 return _jsr_xhandlers;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 void GraphBuilder::ScopeData::set_scope(IRScope* scope) {
a61af66fc99e Initial load
duke
parents:
diff changeset
745 _scope = scope;
a61af66fc99e Initial load
duke
parents:
diff changeset
746 bool parent_has_handler = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
747 if (parent() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 parent_has_handler = parent()->has_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
750 _has_handler = parent_has_handler || scope->xhandlers()->has_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753
a61af66fc99e Initial load
duke
parents:
diff changeset
754 void GraphBuilder::ScopeData::set_inline_cleanup_info(BlockBegin* block,
a61af66fc99e Initial load
duke
parents:
diff changeset
755 Instruction* return_prev,
a61af66fc99e Initial load
duke
parents:
diff changeset
756 ValueStack* return_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 _cleanup_block = block;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 _cleanup_return_prev = return_prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 _cleanup_state = return_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762
a61af66fc99e Initial load
duke
parents:
diff changeset
763 void GraphBuilder::ScopeData::add_to_work_list(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 if (_work_list == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 _work_list = new BlockList();
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 if (!block->is_set(BlockBegin::is_on_work_list_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // Do not start parsing the continuation block while in a
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // sub-scope
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if (parsing_jsr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 if (block == jsr_continuation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
773 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 if (block == continuation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
777 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 block->set(BlockBegin::is_on_work_list_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 _work_list->push(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 sort_top_into_worklist(_work_list, block);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 void GraphBuilder::sort_top_into_worklist(BlockList* worklist, BlockBegin* top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
789 assert(worklist->top() == top, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // sort block descending into work list
a61af66fc99e Initial load
duke
parents:
diff changeset
791 const int dfn = top->depth_first_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert(dfn != -1, "unknown depth first number");
a61af66fc99e Initial load
duke
parents:
diff changeset
793 int i = worklist->length()-2;
a61af66fc99e Initial load
duke
parents:
diff changeset
794 while (i >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 BlockBegin* b = worklist->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if (b->depth_first_number() < dfn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797 worklist->at_put(i+1, b);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
799 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801 i --;
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if (i >= -1) worklist->at_put(i + 1, top);
a61af66fc99e Initial load
duke
parents:
diff changeset
804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806
a61af66fc99e Initial load
duke
parents:
diff changeset
807 BlockBegin* GraphBuilder::ScopeData::remove_from_work_list() {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (is_work_list_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 return _work_list->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 bool GraphBuilder::ScopeData::is_work_list_empty() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
816 return (_work_list == NULL || _work_list->length() == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819
a61af66fc99e Initial load
duke
parents:
diff changeset
820 void GraphBuilder::ScopeData::setup_jsr_xhandlers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
821 assert(parsing_jsr(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // clone all the exception handlers from the scope
a61af66fc99e Initial load
duke
parents:
diff changeset
823 XHandlers* handlers = new XHandlers(scope()->xhandlers());
a61af66fc99e Initial load
duke
parents:
diff changeset
824 const int n = handlers->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
825 for (int i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // The XHandlers need to be adjusted to dispatch to the cloned
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // handler block instead of the default one but the synthetic
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // unlocker needs to be handled specially. The synthetic unlocker
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // should be left alone since there can be only one and all code
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // should dispatch to the same one.
a61af66fc99e Initial load
duke
parents:
diff changeset
831 XHandler* h = handlers->handler_at(i);
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1295
diff changeset
832 assert(h->handler_bci() != SynchronizationEntryBCI, "must be real");
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1295
diff changeset
833 h->set_entry_block(block_at(h->handler_bci()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835 _jsr_xhandlers = handlers;
a61af66fc99e Initial load
duke
parents:
diff changeset
836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 int GraphBuilder::ScopeData::num_returns() {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (parsing_jsr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 return parent()->num_returns();
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 return _num_returns;
a61af66fc99e Initial load
duke
parents:
diff changeset
844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 void GraphBuilder::ScopeData::incr_num_returns() {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 if (parsing_jsr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
849 parent()->incr_num_returns();
a61af66fc99e Initial load
duke
parents:
diff changeset
850 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 ++_num_returns;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Implementation of GraphBuilder
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 #define INLINE_BAILOUT(msg) { inline_bailout(msg); return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 void GraphBuilder::load_constant() {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 ciConstant con = stream()->get_constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
863 if (con.basic_type() == T_ILLEGAL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
864 BAILOUT("could not resolve a constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
865 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 ValueType* t = illegalType;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 ValueStack* patch_state = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 switch (con.basic_type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 case T_BOOLEAN: t = new IntConstant (con.as_boolean()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
870 case T_BYTE : t = new IntConstant (con.as_byte ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
871 case T_CHAR : t = new IntConstant (con.as_char ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
872 case T_SHORT : t = new IntConstant (con.as_short ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
873 case T_INT : t = new IntConstant (con.as_int ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
874 case T_LONG : t = new LongConstant (con.as_long ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 case T_FLOAT : t = new FloatConstant (con.as_float ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
876 case T_DOUBLE : t = new DoubleConstant (con.as_double ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 case T_ARRAY : t = new ArrayConstant (con.as_object ()->as_array ()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
878 case T_OBJECT :
a61af66fc99e Initial load
duke
parents:
diff changeset
879 {
a61af66fc99e Initial load
duke
parents:
diff changeset
880 ciObject* obj = con.as_object();
1602
136b78722a08 6939203: JSR 292 needs method handle constants
jrose
parents: 1584
diff changeset
881 if (!obj->is_loaded()
136b78722a08 6939203: JSR 292 needs method handle constants
jrose
parents: 1584
diff changeset
882 || (PatchALot && obj->klass() != ciEnv::current()->String_klass())) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
883 patch_state = copy_state_before();
1602
136b78722a08 6939203: JSR 292 needs method handle constants
jrose
parents: 1584
diff changeset
884 t = new ObjectConstant(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
885 } else {
1602
136b78722a08 6939203: JSR 292 needs method handle constants
jrose
parents: 1584
diff changeset
886 assert(!obj->is_klass(), "must be java_mirror of klass");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
887 t = new InstanceConstant(obj->as_instance());
a61af66fc99e Initial load
duke
parents:
diff changeset
888 }
a61af66fc99e Initial load
duke
parents:
diff changeset
889 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
891 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893 Value x;
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (patch_state != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 x = new Constant(t, patch_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
897 x = new Constant(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899 push(t, append(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 void GraphBuilder::load_local(ValueType* type, int index) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
905 Value x = state()->local_at(index);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
906 assert(x != NULL && !x->type()->is_illegal(), "access of illegal local variable");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
907 push(type, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910
a61af66fc99e Initial load
duke
parents:
diff changeset
911 void GraphBuilder::store_local(ValueType* type, int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
913 store_local(state(), x, type, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
915
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 void GraphBuilder::store_local(ValueStack* state, Value x, ValueType* type, int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (parsing_jsr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // We need to do additional tracking of the location of the return
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // address for jsrs since we don't handle arbitrary jsr/ret
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // constructs. Here we are figuring out in which circumstances we
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // need to bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
923 if (x->type()->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
924 scope_data()->set_jsr_return_address_local(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // Also check parent jsrs (if any) at this time to see whether
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // they are using this local. We don't handle skipping over a
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // ret.
a61af66fc99e Initial load
duke
parents:
diff changeset
929 for (ScopeData* cur_scope_data = scope_data()->parent();
a61af66fc99e Initial load
duke
parents:
diff changeset
930 cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 cur_scope_data = cur_scope_data->parent()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
932 if (cur_scope_data->jsr_return_address_local() == index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 BAILOUT("subroutine overwrites return address from previous subroutine");
a61af66fc99e Initial load
duke
parents:
diff changeset
934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
936 } else if (index == scope_data()->jsr_return_address_local()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 scope_data()->set_jsr_return_address_local(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 state->store_local(index, round_fp(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 void GraphBuilder::load_indexed(BasicType type) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
946 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
947 Value index = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
948 Value array = apop();
a61af66fc99e Initial load
duke
parents:
diff changeset
949 Value length = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
950 if (CSEArrayLength ||
a61af66fc99e Initial load
duke
parents:
diff changeset
951 (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
952 (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
953 length = append(new ArrayLength(array, state_before));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
955 push(as_ValueType(type), append(new LoadIndexed(array, index, length, type, state_before)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958
a61af66fc99e Initial load
duke
parents:
diff changeset
959 void GraphBuilder::store_indexed(BasicType type) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
960 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
961 Value value = pop(as_ValueType(type));
a61af66fc99e Initial load
duke
parents:
diff changeset
962 Value index = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
963 Value array = apop();
a61af66fc99e Initial load
duke
parents:
diff changeset
964 Value length = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 if (CSEArrayLength ||
a61af66fc99e Initial load
duke
parents:
diff changeset
966 (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
967 (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
968 length = append(new ArrayLength(array, state_before));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
969 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
970 StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
971 append(result);
459
3a86a8dcf27c 6756768: C1 generates invalid code
never
parents: 0
diff changeset
972 _memory->store_value(value);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
973
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
974 if (type == T_OBJECT && is_profiling()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
975 // Note that we'd collect profile data in this method if we wanted it.
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
976 compilation()->set_would_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
977
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
978 if (profile_checkcasts()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
979 result->set_profiled_method(method());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
980 result->set_profiled_bci(bci());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
981 result->set_should_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
982 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
983 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 void GraphBuilder::stack_op(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
988 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 case Bytecodes::_pop:
a61af66fc99e Initial load
duke
parents:
diff changeset
990 { state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 case Bytecodes::_pop2:
a61af66fc99e Initial load
duke
parents:
diff changeset
994 { state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
995 state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
997 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 case Bytecodes::_dup:
a61af66fc99e Initial load
duke
parents:
diff changeset
999 { Value w = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 state()->raw_push(w);
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 state()->raw_push(w);
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 case Bytecodes::_dup_x1:
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 case Bytecodes::_dup_x2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 Value w3 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 state()->raw_push(w3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 case Bytecodes::_dup2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 case Bytecodes::_dup2_x1:
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 Value w3 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 state()->raw_push(w3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 case Bytecodes::_dup2_x2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 Value w3 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 Value w4 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 state()->raw_push(w4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 state()->raw_push(w3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 case Bytecodes::_swap:
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1069 void GraphBuilder::arithmetic_op(ValueType* type, Bytecodes::Code code, ValueStack* state_before) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // NOTE: strictfp can be queried from current method since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // inline methods with differing strictfp bits
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1074 Value res = new ArithmeticOp(code, x, y, method()->is_strict(), state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // Note: currently single-precision floating-point rounding on Intel is handled at the LIRGenerator level
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 res = append(res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 res = round_fp(res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 push(type, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 void GraphBuilder::negate_op(ValueType* type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 push(type, append(new NegateOp(pop(type))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 void GraphBuilder::shift_op(ValueType* type, Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 Value s = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // try to simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // Note: This code should go into the canonicalizer as soon as it can
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // can handle canonicalized forms that contain more than one node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 if (CanonicalizeNodes && code == Bytecodes::_iushr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // pattern: x >>> s
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 IntConstant* s1 = s->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if (s1 != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 // pattern: x >>> s1, with s1 constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 ShiftOp* l = x->as_ShiftOp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 if (l != NULL && l->op() == Bytecodes::_ishl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // pattern: (a << b) >>> s1
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 IntConstant* s0 = l->y()->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 if (s0 != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // pattern: (a << s0) >>> s1
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 const int s0c = s0->value() & 0x1F; // only the low 5 bits are significant for shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 const int s1c = s1->value() & 0x1F; // only the low 5 bits are significant for shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 if (s0c == s1c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 if (s0c == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // pattern: (a << 0) >>> 0 => simplify to: a
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 ipush(l->x());
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // pattern: (a << s0c) >>> s0c => simplify to: a & m, with m constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 assert(0 < s0c && s0c < BitsPerInt, "adjust code below to handle corner cases");
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 const int m = (1 << (BitsPerInt - s0c)) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 Value s = append(new Constant(new IntConstant(m)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 ipush(append(new LogicOp(Bytecodes::_iand, l->x(), s)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // could not simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 push(type, append(new ShiftOp(code, x, s)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1128
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 void GraphBuilder::logic_op(ValueType* type, Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 push(type, append(new LogicOp(code, x, y)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 void GraphBuilder::compare_op(ValueType* type, Bytecodes::Code code) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1138 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 ipush(append(new CompareOp(code, x, y, state_before)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 void GraphBuilder::convert(Bytecodes::Code op, BasicType from, BasicType to) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 push(as_ValueType(to), append(new Convert(op, pop(as_ValueType(from)), as_ValueType(to))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 void GraphBuilder::increment() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 int index = stream()->get_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 int delta = stream()->is_wide() ? (signed short)Bytes::get_Java_u2(stream()->cur_bcp() + 4) : (signed char)(stream()->cur_bcp()[2]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 load_local(intType, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 ipush(append(new Constant(new IntConstant(delta))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 arithmetic_op(intType, Bytecodes::_iadd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 store_local(intType, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 void GraphBuilder::_goto(int from_bci, int to_bci) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1161 Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1162 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1163 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1164 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1165 if (profile_branches()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1166 x->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1167 x->set_profiled_bci(bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1168 x->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1169 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1170 append(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 BlockBegin* tsux = block_at(stream()->get_dest());
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 BlockBegin* fsux = block_at(stream()->next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1178 Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1179
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1180 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1181 If* if_node = i->as_If();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1182 if (if_node != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1183 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1184 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1185 // At level 2 we need the proper bci to count backedges
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1186 if_node->set_profiled_bci(bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1187 if (profile_branches()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1188 // Successors can be rotated by the canonicalizer, check for this case.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1189 if_node->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1190 if_node->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1191 if (if_node->tsux() == fsux) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1192 if_node->set_swapped(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1193 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1194 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1195 return;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1196 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1197
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1198 // Check if this If was reduced to Goto.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1199 Goto *goto_node = i->as_Goto();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1200 if (goto_node != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1201 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1202 if (profile_branches()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1203 goto_node->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1204 goto_node->set_profiled_bci(bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1205 goto_node->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1206 // Find out which successor is used.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1207 if (goto_node->default_sux() == tsux) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1208 goto_node->set_direction(Goto::taken);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1209 } else if (goto_node->default_sux() == fsux) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1210 goto_node->set_direction(Goto::not_taken);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1211 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1212 ShouldNotReachHere();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1213 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1214 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1215 return;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1216 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219
a61af66fc99e Initial load
duke
parents:
diff changeset
1220
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 void GraphBuilder::if_zero(ValueType* type, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 Value y = append(new Constant(intZero));
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1223 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 Value x = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if_node(x, cond, y, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 void GraphBuilder::if_null(ValueType* type, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 Value y = append(new Constant(objectNull));
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1231 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 Value x = apop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 if_node(x, cond, y, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 void GraphBuilder::if_same(ValueType* type, If::Condition cond) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1238 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 if_node(x, cond, y, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 void GraphBuilder::jsr(int dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // We only handle well-formed jsrs (those which are "block-structured").
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // If the bytecodes are strange (jumping out of a jsr block) then we
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // might end up trying to re-parse a block containing a jsr which
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // has already been activated. Watch for this case and bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 for (ScopeData* cur_scope_data = scope_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 cur_scope_data = cur_scope_data->parent()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 if (cur_scope_data->jsr_entry_bci() == dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 BAILOUT("too-complicated jsr/ret structure");
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1257
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 push(addressType, append(new Constant(new AddressConstant(next_bci()))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 if (!try_inline_jsr(dest)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 return; // bailed out while parsing and inlining subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 void GraphBuilder::ret(int local_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 if (!parsing_jsr()) BAILOUT("ret encountered while not parsing subroutine");
a61af66fc99e Initial load
duke
parents:
diff changeset
1267
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 if (local_index != scope_data()->jsr_return_address_local()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 BAILOUT("can not handle complicated jsr/ret constructs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // Rets simply become (NON-SAFEPOINT) gotos to the jsr continuation
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 append(new Goto(scope_data()->jsr_continuation(), false));
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 void GraphBuilder::table_switch() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(method()->code() + bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 const int l = switch_->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 if (CanonicalizeNodes && l == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // total of 2 successors => use If instead of switch
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // Note: This code should go into the canonicalizer as soon as it can
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // can handle canonicalized forms that contain more than one node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 Value key = append(new Constant(new IntConstant(switch_->low_key())));
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 BlockBegin* tsux = block_at(bci() + switch_->dest_offset_at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 BlockBegin* fsux = block_at(bci() + switch_->default_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1288 ValueStack* state_before = is_bb ? copy_state_before() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // collect successors
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 BlockList* sux = new BlockList(l + 1, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 bool has_bb = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 for (i = 0; i < l; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 sux->at_put(i, block_at(bci() + switch_->dest_offset_at(i)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 if (switch_->dest_offset_at(i) < 0) has_bb = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // add default successor
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 sux->at_put(i, block_at(bci() + switch_->default_offset()));
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1301 ValueStack* state_before = has_bb ? copy_state_before() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 append(new TableSwitch(ipop(), sux, switch_->low_key(), state_before, has_bb));
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1305
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 void GraphBuilder::lookup_switch() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(method()->code() + bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 const int l = switch_->number_of_pairs();
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 if (CanonicalizeNodes && l == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // total of 2 successors => use If instead of switch
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // Note: This code should go into the canonicalizer as soon as it can
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // can handle canonicalized forms that contain more than one node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // simplify to If
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 LookupswitchPair* pair = switch_->pair_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 Value key = append(new Constant(new IntConstant(pair->match())));
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 BlockBegin* tsux = block_at(bci() + pair->offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 BlockBegin* fsux = block_at(bci() + switch_->default_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1320 ValueStack* state_before = is_bb ? copy_state_before() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // collect successors & keys
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 BlockList* sux = new BlockList(l + 1, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 intArray* keys = new intArray(l, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 bool has_bb = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 for (i = 0; i < l; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 LookupswitchPair* pair = switch_->pair_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 if (pair->offset() < 0) has_bb = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 sux->at_put(i, block_at(bci() + pair->offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 keys->at_put(i, pair->match());
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 // add default successor
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 sux->at_put(i, block_at(bci() + switch_->default_offset()));
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1336 ValueStack* state_before = has_bb ? copy_state_before() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1340
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 void GraphBuilder::call_register_finalizer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // If the receiver requires finalization then emit code to perform
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // the registration on return.
a61af66fc99e Initial load
duke
parents:
diff changeset
1344
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // Gather some type information about the receiver
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1346 Value receiver = state()->local_at(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 assert(receiver != NULL, "must have a receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 ciType* declared_type = receiver->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 ciType* exact_type = receiver->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 if (exact_type == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 receiver->as_Local() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 receiver->as_Local()->java_index() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 ciInstanceKlass* ik = compilation()->method()->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 if (ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 exact_type = ik;
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 } else if (UseCHA && !(ik->has_subklass() || ik->is_interface())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // test class is leaf class
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 compilation()->dependency_recorder()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 exact_type = ik;
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 declared_type = ik;
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1364
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // see if we know statically that registration isn't required
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 bool needs_check = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 if (exact_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 needs_check = exact_type->as_instance_klass()->has_finalizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 } else if (declared_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 ciInstanceKlass* ik = declared_type->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 if (!Dependencies::has_finalizable_subclass(ik)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 compilation()->dependency_recorder()->assert_has_no_finalizable_subclasses(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 needs_check = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 if (needs_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // Perform the registration of finalizable objects.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1379 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 load_local(objectType, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 append_split(new Intrinsic(voidType, vmIntrinsics::_Object_init,
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 state()->pop_arguments(1),
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1383 true, state_before, true));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 void GraphBuilder::method_return(Value x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 if (RegisterFinalizersAtInit &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 method()->intrinsic_id() == vmIntrinsics::_Object_init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 call_register_finalizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1393
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // Check to see whether we are inlining. If so, Return
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // instructions become Gotos to the continuation point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 if (continuation() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
1398
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 // If the inlined method is synchronized, the monitor must be
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // released before we jump to the continuation block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 if (method()->is_synchronized()) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1402 assert(state()->locks_size() == 1, "receiver must be locked here");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1403 monitorexit(state()->lock_at(0), SynchronizationEntryBCI);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1406 // State at end of inlined method is the state of the caller
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1407 // without the method parameters on stack, including the
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1408 // return value, if any, of the inlined method on operand stack.
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1409 set_state(state()->caller_state()->copy_for_parsing());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 if (x != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 state()->push(x->type(), x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 Goto* goto_callee = new Goto(continuation(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1414
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // See whether this is the first return; if so, store off some
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // of the state for later examination
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 if (num_returns() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 set_inline_cleanup_info(_block, _last, state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1420
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // The current bci() is in the wrong scope, so use the bci() of
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // the continuation point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 append_with_bci(goto_callee, scope_data()->continuation()->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 incr_num_returns();
a61af66fc99e Initial load
duke
parents:
diff changeset
1425
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1428
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 state()->truncate_stack(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 if (method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // perform the unlocking before exiting the method
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 Value receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if (!method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 receiver = _initial_state->local_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 receiver = append(new Constant(new ClassConstant(method()->holder())));
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 append_split(new MonitorExit(receiver, state()->unlock()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1440
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 append(new Return(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 void GraphBuilder::access_field(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 ciField* field = stream()->get_field(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 ciInstanceKlass* holder = field->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 BasicType field_type = field->type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 ValueType* type = as_ValueType(field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // call will_link again to determine if the field is valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 const bool is_loaded = holder->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 field->will_link(method()->holder(), code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 const bool is_initialized = is_loaded && holder->is_initialized();
a61af66fc99e Initial load
duke
parents:
diff changeset
1455
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1456 ValueStack* state_before = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 if (!is_initialized || PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // save state before instruction for debug info when
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // deoptimization happens during patching
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1460 state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 Value obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // commoning of class constants should only occur if the class is
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // fully initialized and resolved in this constant pool. The will_link test
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // above essentially checks if this class is resolved in this constant pool
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // so, the is_initialized flag should be suffiect.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1469 if (state_before != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // build a patching constant
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1471 obj = new Constant(new ClassConstant(holder), state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 obj = new Constant(new ClassConstant(holder));
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 const int offset = is_loaded ? field->offset() : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 case Bytecodes::_getstatic: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // check for compile-time constants, i.e., initialized static final fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 Instruction* constant = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 if (field->is_constant() && !PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 ciConstant field_val = field->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 BasicType field_type = field_val.basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 switch (field_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 case T_OBJECT:
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
1489 if (field_val.as_object()->should_be_constant()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 constant = new Constant(as_ValueType(field_val));
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1493
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 constant = new Constant(as_ValueType(field_val));
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 if (constant != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 push(type, append(constant));
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 } else {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1501 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1502 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1503 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 push(type, append(new LoadField(append(obj), offset, field, true,
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1505 state_before, is_loaded, is_initialized)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 case Bytecodes::_putstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 { Value val = pop(type);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1511 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1512 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1513 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1514 append(new StoreField(append(obj), offset, field, val, true, state_before, is_loaded, is_initialized));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 case Bytecodes::_getfield :
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1519 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1520 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1521 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1522 LoadField* load = new LoadField(apop(), offset, field, false, state_before, is_loaded, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 Value replacement = is_loaded ? _memory->load(load) : load;
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 if (replacement != load) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1525 assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 push(type, replacement);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 push(type, append(load));
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1532
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 case Bytecodes::_putfield :
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 { Value val = pop(type);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1535 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1536 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1537 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1538 StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, is_loaded, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 if (is_loaded) store = _memory->store(store);
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 if (store != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 append(store);
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 Dependencies* GraphBuilder::dependency_recorder() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 assert(DeoptC1, "need debug information");
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 return compilation()->dependency_recorder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556
a61af66fc99e Initial load
duke
parents:
diff changeset
1557
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 void GraphBuilder::invoke(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 ciMethod* target = stream()->get_method(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // we have to make sure the argument size (incl. the receiver)
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // is correct for compilation (the call would fail later during
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 // linkage anyway) - was bug (gri 7/28/99)
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 if (target->is_loaded() && target->is_static() != (code == Bytecodes::_invokestatic)) BAILOUT("will cause link error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 ciInstanceKlass* klass = target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1566
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // check if CHA possible: if so, change the code to invoke_special
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 ciInstanceKlass* calling_klass = method()->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 ciKlass* holder = stream()->get_declared_method_holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 ciInstanceKlass* actual_recv = callee_holder;
a61af66fc99e Initial load
duke
parents:
diff changeset
1572
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 // some methods are obviously bindable without any type checks so
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // convert them directly to an invokespecial.
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 if (target->is_loaded() && !target->is_abstract() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 code = Bytecodes::_invokespecial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1579
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 // NEEDS_CLEANUP
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // I've added the target-is_loaded() test below but I don't really understand
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // how klass->is_loaded() can be true and yet target->is_loaded() is false.
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // this happened while running the JCK invokevirtual tests under doit. TKR
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 ciMethod* cha_monomorphic_target = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 ciMethod* exact_target = NULL;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1586 if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1587 !target->is_method_handle_invoke()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 Value receiver = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 ciInstanceKlass* receiver_klass = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 bool type_is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // try to find a precise receiver type
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 if (will_link && !target->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 int index = state()->stack_size() - (target->arg_size_no_receiver() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 receiver = state()->stack_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 ciType* type = receiver->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 if (type != NULL && type->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 receiver_klass = (ciInstanceKlass*) type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 if (type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 type = receiver->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 if (type != NULL && type->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 receiver_klass = (ciInstanceKlass*) type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 if (receiver_klass->is_leaf_type() && !receiver_klass->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // Insert a dependency on this type since
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 // find_monomorphic_target may assume it's already done.
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 dependency_recorder()->assert_leaf_type(receiver_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 if (receiver_klass != NULL && type_is_exact &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 receiver_klass->is_loaded() && code != Bytecodes::_invokespecial) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // If we have the exact receiver type we can bind directly to
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // the method to call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 exact_target = target->resolve_invoke(calling_klass, receiver_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 if (exact_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 target = exact_target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 code = Bytecodes::_invokespecial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 if (receiver_klass != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 receiver_klass->is_subtype_of(actual_recv) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 actual_recv->is_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 actual_recv = receiver_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 (code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // Use CHA on the receiver to select a more precise method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 } else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // if there is only one implementor of this interface then we
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // may be able bind this invoke directly to the implementing
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // klass but we need both a dependence on the single interface
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // and on the method we bind to. Additionally since all we know
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 // about the receiver type is the it's supposed to implement the
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // interface we have to insert a check that it's the class we
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // expect. Interface types are not checked by the verifier so
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // they are roughly equivalent to Object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 ciInstanceKlass* singleton = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 if (target->holder()->nof_implementors() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 singleton = target->holder()->implementor(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 if (singleton) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // If CHA is able to bind this invoke then update the class
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // to match that class, otherwise klass will refer to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 klass = cha_monomorphic_target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 actual_recv = target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1656
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // insert a check it's really the expected class.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1658 CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 c->set_incompatible_class_change_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 c->set_direct_compare(klass->is_final());
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 append_split(c);
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 if (cha_monomorphic_target->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // Do not optimize for abstract methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 cha_monomorphic_target = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 if (!(target->is_final_method())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 // If we inlined because CHA revealed only a single target method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 // then we are dependent on that target method not getting overridden
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // by dynamic class loading. Be sure to test the "static" receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // dest_method here, as opposed to the actual receiver, which may
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 // falsely lead us to believe that the receiver is final or private.
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 code = Bytecodes::_invokespecial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 // check if we could do inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 if (!PatchALot && Inline && klass->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 && target->will_link(klass, callee_holder, code)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // callee is known => check if we have static binding
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 assert(target->is_loaded(), "callee must be known");
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 if (code == Bytecodes::_invokestatic
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 || code == Bytecodes::_invokespecial
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 || code == Bytecodes::_invokevirtual && target->is_final_method()
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // static binding => check if callee is ok
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 ciMethod* inline_target = (cha_monomorphic_target != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 ? cha_monomorphic_target
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 : target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
1701
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // printing
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 if (PrintInlining && !res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // if it was successfully inlined, then it was already printed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 print_inline_result(inline_target, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 clear_inline_bailout();
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 if (res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // Register dependence if JVMTI has either breakpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 // setting or hotswapping of methods capabilities since they may
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 // cause deoptimization.
780
c96bf21b756f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 726
diff changeset
1714 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 dependency_recorder()->assert_evol_method(inline_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // If we attempted an inline which did not succeed because of a
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // bailout during construction of the callee graph, the entire
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // compilation has to be aborted. This is fairly rare and currently
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // seems to only occur for jasm-generated classes which contain
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // jsr/ret pairs which are not associated with finally clauses and
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // do not have exception handlers in the containing method, and are
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // therefore not caught early enough to abort the inlining without
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // corrupting the graph. (We currently bail out with a non-empty
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 // stack at a ret in these situations.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // inlining not successful => standard invoke
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1733 bool is_loaded = target->is_loaded();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1734 bool has_receiver =
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1735 code == Bytecodes::_invokespecial ||
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1736 code == Bytecodes::_invokevirtual ||
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1737 code == Bytecodes::_invokeinterface;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1738 bool is_invokedynamic = code == Bytecodes::_invokedynamic;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 ValueType* result_type = as_ValueType(target->return_type());
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1740
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1741 // We require the debug info to be the "state before" because
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1742 // invokedynamics may deoptimize.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1743 ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling();
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1744
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 Values* args = state()->pop_arguments(target->arg_size_no_receiver());
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1746 Value recv = has_receiver ? apop() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 int vtable_index = methodOopDesc::invalid_vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
1748
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // Currently only supported on Sparc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // The UseInlineCaches only controls dispatch to invokevirtuals for
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 // loaded classes which we weren't able to statically bind.
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 && !target->can_be_statically_bound()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // Find a vtable index if one is available
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 vtable_index = target->resolve_vtable_index(calling_klass, callee_holder);
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 if (recv != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 (code == Bytecodes::_invokespecial ||
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1762 !is_loaded || target->is_final())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // invokespecial always needs a NULL check. invokevirtual where
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // the target is final or where it's not known that whether the
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 // target is final requires a NULL check. Otherwise normal
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 // invokevirtual will perform the null check during the lookup
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // logic or the unverified entry point. Profiling of calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // requires that the null check is performed in all cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 null_check(recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1771
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1772 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1773 if (recv != NULL && profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1774 null_check(recv);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 }
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1776 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1777 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1778
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1779 if (profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1780 assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1781 ciKlass* target_klass = NULL;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1782 if (cha_monomorphic_target != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1783 target_klass = cha_monomorphic_target->holder();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1784 } else if (exact_target != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1785 target_klass = exact_target->holder();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1786 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1787 profile_call(recv, target_klass);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1788 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1790
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1791 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 // push result
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 append_split(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1794
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 if (result_type != voidType) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 push(result_type, round_fp(result));
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 push(result_type, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1803
a61af66fc99e Initial load
duke
parents:
diff changeset
1804
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 void GraphBuilder::new_instance(int klass_index) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1806 ValueStack* state_before = copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 ciKlass* klass = stream()->get_klass(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 assert(klass->is_instance_klass(), "must be an instance klass");
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1810 NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 _memory->new_instance(new_instance);
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 apush(append_split(new_instance));
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1814
a61af66fc99e Initial load
duke
parents:
diff changeset
1815
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 void GraphBuilder::new_type_array() {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1817 ValueStack* state_before = copy_state_exhandling();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1818 apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 void GraphBuilder::new_object_array() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1825 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 NewArray* n = new NewObjectArray(klass, ipop(), state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 apush(append_split(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1829
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 bool GraphBuilder::direct_compare(ciKlass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 if (k->is_loaded() && k->is_instance_klass() && !UseSlowPath) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 ciInstanceKlass* ik = k->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 if (ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 if (DeoptC1 && UseCHA && !(ik->has_subklass() || ik->is_interface())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 // test class is leaf class
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 dependency_recorder()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 void GraphBuilder::check_cast(int klass_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1851 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 CheckCast* c = new CheckCast(klass, apop(), state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 apush(append_split(c));
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 c->set_direct_compare(direct_compare(klass));
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1855
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1856 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1857 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1858 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1859
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1860 if (profile_checkcasts()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1861 c->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1862 c->set_profiled_bci(bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1863 c->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1864 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1867
a61af66fc99e Initial load
duke
parents:
diff changeset
1868
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 void GraphBuilder::instance_of(int klass_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1872 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 InstanceOf* i = new InstanceOf(klass, apop(), state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 ipush(append_split(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 i->set_direct_compare(direct_compare(klass));
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1876
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1877 if (is_profiling()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1878 // Note that we'd collect profile data in this method if we wanted it.
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1879 compilation()->set_would_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1880
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1881 if (profile_checkcasts()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1882 i->set_profiled_method(method());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1883 i->set_profiled_bci(bci());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1884 i->set_should_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1885 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
1886 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1888
a61af66fc99e Initial load
duke
parents:
diff changeset
1889
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 void GraphBuilder::monitorenter(Value x, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 // save state before locking in case of deoptimization after a NullPointerException
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1892 ValueStack* state_before = copy_state_for_exception_with_bci(bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1893 append_with_bci(new MonitorEnter(x, state()->lock(x), state_before), bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1896
a61af66fc99e Initial load
duke
parents:
diff changeset
1897
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 void GraphBuilder::monitorexit(Value x, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 append_with_bci(new MonitorExit(x, state()->unlock()), bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1902
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 void GraphBuilder::new_multi_array(int dimensions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1907 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1908
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 Values* dims = new Values(dimensions, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 // fill in all dimensions
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 int i = dimensions;
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 while (i-- > 0) dims->at_put(i, ipop());
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 // create array
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 NewArray* n = new NewMultiArray(klass, dims, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 apush(append_split(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1917
a61af66fc99e Initial load
duke
parents:
diff changeset
1918
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 void GraphBuilder::throw_op(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 // We require that the debug info for a Throw be the "state before"
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 // the Throw (i.e., exception oop is still on TOS)
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1922 ValueStack* state_before = copy_state_before_with_bci(bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 Throw* t = new Throw(apop(), state_before);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1924 // operand stack not needed after a throw
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1925 state()->truncate_stack(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 append_with_bci(t, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 Value GraphBuilder::round_fp(Value fp_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 // no rounding needed if SSE2 is used
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 if (RoundFPResults && UseSSE < 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // Must currently insert rounding node for doubleword values that
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 // are results of expressions (i.e., not loads from memory or
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // constants)
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 if (fp_value->type()->tag() == doubleTag &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 fp_value->as_Constant() == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 fp_value->as_Local() == NULL && // method parameters need no rounding
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 fp_value->as_RoundFP() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 return append(new RoundFP(fp_value));
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 return fp_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1945
a61af66fc99e Initial load
duke
parents:
diff changeset
1946
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1948 Canonicalizer canon(compilation(), instr, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 Instruction* i1 = canon.canonical();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1950 if (i1->is_linked() || !i1->can_be_linked()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // Canonicalizer returned an instruction which was already
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 // appended so simply return it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 return i1;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1954 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1955
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1956 if (UseLocalValueNumbering) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // Lookup the instruction in the ValueMap and add it to the map if
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // it's not found.
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 Instruction* i2 = vmap()->find_insert(i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 if (i2 != i1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // found an entry in the value map, so just return it.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1962 assert(i2->is_linked(), "should already be linked");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 return i2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 }
459
3a86a8dcf27c 6756768: C1 generates invalid code
never
parents: 0
diff changeset
1965 ValueNumberingEffects vne(vmap());
3a86a8dcf27c 6756768: C1 generates invalid code
never
parents: 0
diff changeset
1966 i1->visit(&vne);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1968
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1969 // i1 was not eliminated => append it
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1970 assert(i1->next() == NULL, "shouldn't already be linked");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1971 _last = _last->set_next(i1, canon.bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1972
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1973 if (++_instruction_count >= InstructionCountCutoff && !bailed_out()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1974 // set the bailout state but complete normal processing. We
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1975 // might do a little more work before noticing the bailout so we
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1976 // want processing to continue normally until it's noticed.
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1977 bailout("Method and/or inlining is too large");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1978 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1979
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 #ifndef PRODUCT
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1981 if (PrintIRDuringConstruction) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1982 InstructionPrinter ip;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1983 ip.print_line(i1);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1984 if (Verbose) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1985 state()->print();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1986 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1987 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1988 #endif
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1989
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1990 // save state after modification of operand stack for StateSplit instructions
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1991 StateSplit* s = i1->as_StateSplit();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1992 if (s != NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1993 if (EliminateFieldAccess) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1994 Intrinsic* intrinsic = s->as_Intrinsic();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1995 if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1996 _memory->kill();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1999 s->set_state(state()->copy(ValueStack::StateAfter, canon.bci()));
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2000 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2001
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2002 // set up exception handlers for this instruction if necessary
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2003 if (i1->can_trap()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2004 i1->set_exception_handlers(handle_exception(i1));
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2005 assert(i1->exception_state() != NULL || !i1->needs_exception_state() || bailed_out(), "handle_exception must set exception state");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 return i1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2009
a61af66fc99e Initial load
duke
parents:
diff changeset
2010
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 Instruction* GraphBuilder::append(Instruction* instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 assert(instr->as_StateSplit() == NULL || instr->as_BlockEnd() != NULL, "wrong append used");
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 return append_with_bci(instr, bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
a61af66fc99e Initial load
duke
parents:
diff changeset
2016
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 Instruction* GraphBuilder::append_split(StateSplit* instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 return append_with_bci(instr, bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 void GraphBuilder::null_check(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 if (value->as_NewArray() != NULL || value->as_NewInstance() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 Constant* con = value->as_Constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 if (con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 ObjectType* c = con->type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 if (c && c->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 ObjectConstant* oc = c->as_ObjectConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 if (!oc || !oc->value()->is_null_object()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2037 append(new NullCheck(value, copy_state_for_exception()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2039
a61af66fc99e Initial load
duke
parents:
diff changeset
2040
a61af66fc99e Initial load
duke
parents:
diff changeset
2041
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2042 XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2043 if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2044 assert(instruction->exception_state() == NULL
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2045 || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2046 || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()),
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2047 "exception_state should be of exception kind");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 return new XHandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 XHandlers* exception_handlers = new XHandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 ScopeData* cur_scope_data = scope_data();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2053 ValueStack* cur_state = instruction->state_before();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2054 ValueStack* prev_state = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 int scope_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2056
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2057 assert(cur_state != NULL, "state_before must be set");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 do {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2059 int cur_bci = cur_state->bci();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2060 assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci");
a61af66fc99e Initial load
duke
parents:
diff changeset
2062
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 // join with all potential exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 XHandlers* list = cur_scope_data->xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 const int n = list->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 for (int i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 XHandler* h = list->handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 if (h->covers(cur_bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 // h is a potential exception handler => join it
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 compilation()->set_has_exception_handlers(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 BlockBegin* entry = h->entry_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 if (entry == block()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // It's acceptable for an exception handler to cover itself
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 // but we don't handle that in the parser currently. It's
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // very rare so we bailout instead of trying to handle it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 BAILOUT_("exception handler covers itself", exception_handlers);
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 assert(entry->bci() == h->handler_bci(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 assert(entry->bci() == -1 || entry == cur_scope_data->block_at(entry->bci()), "blocks must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // previously this was a BAILOUT, but this is not necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 // now because asynchronous exceptions are not handled this way.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2084 assert(entry->state() == NULL || cur_state->total_locks_size() == entry->state()->total_locks_size(), "locks do not match");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2085
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 // xhandler start with an empty expression stack
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2087 if (cur_state->stack_size() != 0) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2088 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2089 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2090 if (instruction->exception_state() == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2091 instruction->set_exception_state(cur_state);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2092 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2093
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 // Note: Usually this join must work. However, very
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // complicated jsr-ret structures where we don't ret from
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // the subroutine can cause the objects on the monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // stacks to not match because blocks can be parsed twice.
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // The only test case we've seen so far which exhibits this
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 // problem is caught by the infinite recursion test in
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 // GraphBuilder::jsr() if the join doesn't work.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2101 if (!entry->try_merge(cur_state)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 BAILOUT_("error while joining with exception handler, prob. due to complicated jsr/rets", exception_handlers);
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2104
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 // add current state for correct handling of phi functions at begin of xhandler
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2106 int phi_operand = entry->add_exception_state(cur_state);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2107
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 // add entry to the list of xhandlers of this block
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 _block->add_exception_handler(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
2110
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 // add back-edge from xhandler entry to this block
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 if (!entry->is_predecessor(_block)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 entry->add_predecessor(_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2115
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 // clone XHandler because phi_operand and scope_count can not be shared
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 XHandler* new_xhandler = new XHandler(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 new_xhandler->set_phi_operand(phi_operand);
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 new_xhandler->set_scope_count(scope_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 exception_handlers->append(new_xhandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2121
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 // fill in exception handler subgraph lazily
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 cur_scope_data->add_to_work_list(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
2125
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // stop when reaching catchall
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 if (h->catch_type() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 return exception_handlers;
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2133 if (exception_handlers->length() == 0) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2134 // This scope and all callees do not handle exceptions, so the local
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2135 // variables of this scope are not needed. However, the scope itself is
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2136 // required for a correct exception stack trace -> clear out the locals.
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2137 if (_compilation->env()->jvmti_can_access_local_variables()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2138 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2139 } else {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2140 cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2141 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2142 if (prev_state != NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2143 prev_state->set_caller_state(cur_state);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2144 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2145 if (instruction->exception_state() == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2146 instruction->set_exception_state(cur_state);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2147 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2148 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2149
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 // Set up iteration for next time.
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 // If parsing a jsr, do not grab exception handlers from the
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 // parent scopes for this method (already got them, and they
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // needed to be cloned)
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2154
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2155 while (cur_scope_data->parsing_jsr()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2156 cur_scope_data = cur_scope_data->parent();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2158
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2159 assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2160 assert(cur_state->locks_size() == 0 || cur_state->locks_size() == 1, "unlocking must be done in a catchall exception handler");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2161
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2162 prev_state = cur_state;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2163 cur_state = cur_state->caller_state();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2164 cur_scope_data = cur_scope_data->parent();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2165 scope_count++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 } while (cur_scope_data != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2167
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 return exception_handlers;
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2170
a61af66fc99e Initial load
duke
parents:
diff changeset
2171
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // Helper class for simplifying Phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 class PhiSimplifier : public BlockClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 bool _has_substitutions;
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 Value simplify(Value v);
a61af66fc99e Initial load
duke
parents:
diff changeset
2177
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 PhiSimplifier(BlockBegin* start) : _has_substitutions(false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 start->iterate_preorder(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 if (_has_substitutions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 SubstitutionResolver sr(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 void block_do(BlockBegin* b);
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 bool has_substitutions() const { return _has_substitutions; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2188
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 Value PhiSimplifier::simplify(Value v) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 Phi* phi = v->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2192
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 if (phi == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 // no phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 return v;
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 } else if (v->has_subst()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 // already substituted; subst can be phi itself -> simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 return simplify(v->subst());
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 } else if (phi->is_set(Phi::cannot_simplify)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // already tried to simplify phi before
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 } else if (phi->is_set(Phi::visited)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 // break cycles in phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 } else if (phi->type()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 // illegal phi functions are ignored anyway
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2208
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 // mark phi function as processed to break cycles in phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 phi->set(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2212
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 // simplify x = [y, x] and x = [y, y] to y
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 Value subst = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 int opd_count = phi->operand_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 for (int i = 0; i < opd_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 Value opd = phi->operand_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 assert(opd != NULL, "Operand must exist!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 if (opd->type()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 // if one operand is illegal, the entire phi function is illegal
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 phi->make_illegal();
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 phi->clear(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2226
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 Value new_opd = simplify(opd);
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 assert(new_opd != NULL, "Simplified operand must exist!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 if (new_opd != phi && new_opd != subst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 if (subst == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 subst = new_opd;
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // no simplification possible
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 phi->set(Phi::cannot_simplify);
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 phi->clear(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2241
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // sucessfully simplified phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 assert(subst != NULL, "illegal phi function");
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 _has_substitutions = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 phi->clear(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 phi->set_subst(subst);
a61af66fc99e Initial load
duke
parents:
diff changeset
2247
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 if (PrintPhiFunctions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 tty->print_cr("simplified phi function %c%d to %c%d (Block B%d)", phi->type()->tchar(), phi->id(), subst->type()->tchar(), subst->id(), phi->block()->block_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2253
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 return subst;
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2257
a61af66fc99e Initial load
duke
parents:
diff changeset
2258
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 void PhiSimplifier::block_do(BlockBegin* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 for_each_phi_fun(b, phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 simplify(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 for_each_phi_fun(b, phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 assert(phi->operand_count() != 1 || phi->subst() != phi, "missed trivial simplification");
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 ValueStack* state = b->state()->caller_state();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2270 for_each_state_value(state, value,
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2271 Phi* phi = value->as_Phi();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2272 assert(phi == NULL || phi->block() != b, "must not have phi function to simplify in caller state");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2273 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2276
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 // This method is called after all blocks are filled with HIR instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 // It eliminates all Phi functions of the form x = [y, y] and x = [y, x]
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 void GraphBuilder::eliminate_redundant_phis(BlockBegin* start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 PhiSimplifier simplifier(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 void GraphBuilder::connect_to_end(BlockBegin* beg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // setup iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 _block = beg;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2288 _state = beg->state()->copy_for_parsing();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 _last = beg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 iterate_bytecodes_for_block(beg->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2292
a61af66fc99e Initial load
duke
parents:
diff changeset
2293
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 BlockEnd* GraphBuilder::iterate_bytecodes_for_block(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 if (PrintIRDuringConstruction) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 InstructionPrinter ip;
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 ip.print_instr(_block); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 ip.print_stack(_block->state()); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 ip.print_inline_level(_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 ip.print_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 tty->print_cr("locals size: %d stack size: %d", state()->locals_size(), state()->stack_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 _skip_block = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 assert(state() != NULL, "ValueStack missing!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 ciBytecodeStream s(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 s.reset_to_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 int prev_bci = bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 scope_data()->set_stream(&s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 // iterate
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 Bytecodes::Code code = Bytecodes::_illegal;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 bool push_exception = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2315
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 if (block()->is_set(BlockBegin::exception_entry_flag) && block()->next() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 // first thing in the exception entry block should be the exception object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 push_exception = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2320
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 while (!bailed_out() && last()->as_BlockEnd() == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 (code = stream()->next()) != ciBytecodeStream::EOBC() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2324 assert(state()->kind() == ValueStack::Parsing, "invalid state kind");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2325
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 // Check for active jsr during OSR compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 if (compilation()->is_osr_compile()
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 && scope()->is_top_scope()
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 && parsing_jsr()
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 && s.cur_bci() == compilation()->osr_bci()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 bailout("OSR not supported while a jsr is active");
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 if (push_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 apush(append(new ExceptionObject()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 push_exception = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2338
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 // handle bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 case Bytecodes::_nop : /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 case Bytecodes::_aconst_null : apush(append(new Constant(objectNull ))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 case Bytecodes::_iconst_m1 : ipush(append(new Constant(new IntConstant (-1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 case Bytecodes::_iconst_0 : ipush(append(new Constant(intZero ))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 case Bytecodes::_iconst_1 : ipush(append(new Constant(intOne ))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 case Bytecodes::_iconst_2 : ipush(append(new Constant(new IntConstant ( 2)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 case Bytecodes::_iconst_3 : ipush(append(new Constant(new IntConstant ( 3)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 case Bytecodes::_iconst_4 : ipush(append(new Constant(new IntConstant ( 4)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 case Bytecodes::_iconst_5 : ipush(append(new Constant(new IntConstant ( 5)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 case Bytecodes::_lconst_0 : lpush(append(new Constant(new LongConstant ( 0)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 case Bytecodes::_lconst_1 : lpush(append(new Constant(new LongConstant ( 1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 case Bytecodes::_fconst_0 : fpush(append(new Constant(new FloatConstant ( 0)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 case Bytecodes::_fconst_1 : fpush(append(new Constant(new FloatConstant ( 1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 case Bytecodes::_fconst_2 : fpush(append(new Constant(new FloatConstant ( 2)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 case Bytecodes::_dconst_0 : dpush(append(new Constant(new DoubleConstant( 0)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 case Bytecodes::_dconst_1 : dpush(append(new Constant(new DoubleConstant( 1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 case Bytecodes::_bipush : ipush(append(new Constant(new IntConstant(((signed char*)s.cur_bcp())[1])))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 case Bytecodes::_sipush : ipush(append(new Constant(new IntConstant((short)Bytes::get_Java_u2(s.cur_bcp()+1))))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 case Bytecodes::_ldc : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 case Bytecodes::_ldc_w : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 case Bytecodes::_ldc2_w : load_constant(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 case Bytecodes::_iload : load_local(intType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 case Bytecodes::_lload : load_local(longType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 case Bytecodes::_fload : load_local(floatType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 case Bytecodes::_dload : load_local(doubleType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 case Bytecodes::_aload : load_local(instanceType, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 case Bytecodes::_iload_0 : load_local(intType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 case Bytecodes::_iload_1 : load_local(intType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 case Bytecodes::_iload_2 : load_local(intType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 case Bytecodes::_iload_3 : load_local(intType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 case Bytecodes::_lload_0 : load_local(longType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 case Bytecodes::_lload_1 : load_local(longType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 case Bytecodes::_lload_2 : load_local(longType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 case Bytecodes::_lload_3 : load_local(longType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 case Bytecodes::_fload_0 : load_local(floatType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 case Bytecodes::_fload_1 : load_local(floatType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 case Bytecodes::_fload_2 : load_local(floatType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 case Bytecodes::_fload_3 : load_local(floatType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 case Bytecodes::_dload_0 : load_local(doubleType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 case Bytecodes::_dload_1 : load_local(doubleType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 case Bytecodes::_dload_2 : load_local(doubleType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 case Bytecodes::_dload_3 : load_local(doubleType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 case Bytecodes::_aload_0 : load_local(objectType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 case Bytecodes::_aload_1 : load_local(objectType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 case Bytecodes::_aload_2 : load_local(objectType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 case Bytecodes::_aload_3 : load_local(objectType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 case Bytecodes::_iaload : load_indexed(T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 case Bytecodes::_laload : load_indexed(T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 case Bytecodes::_faload : load_indexed(T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 case Bytecodes::_daload : load_indexed(T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 case Bytecodes::_aaload : load_indexed(T_OBJECT); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 case Bytecodes::_baload : load_indexed(T_BYTE ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 case Bytecodes::_caload : load_indexed(T_CHAR ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 case Bytecodes::_saload : load_indexed(T_SHORT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 case Bytecodes::_istore : store_local(intType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 case Bytecodes::_lstore : store_local(longType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 case Bytecodes::_fstore : store_local(floatType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 case Bytecodes::_dstore : store_local(doubleType, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 case Bytecodes::_astore : store_local(objectType, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 case Bytecodes::_istore_0 : store_local(intType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 case Bytecodes::_istore_1 : store_local(intType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 case Bytecodes::_istore_2 : store_local(intType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 case Bytecodes::_istore_3 : store_local(intType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 case Bytecodes::_lstore_0 : store_local(longType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 case Bytecodes::_lstore_1 : store_local(longType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 case Bytecodes::_lstore_2 : store_local(longType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 case Bytecodes::_lstore_3 : store_local(longType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 case Bytecodes::_fstore_0 : store_local(floatType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 case Bytecodes::_fstore_1 : store_local(floatType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 case Bytecodes::_fstore_2 : store_local(floatType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 case Bytecodes::_fstore_3 : store_local(floatType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 case Bytecodes::_dstore_0 : store_local(doubleType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 case Bytecodes::_dstore_1 : store_local(doubleType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 case Bytecodes::_dstore_2 : store_local(doubleType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 case Bytecodes::_dstore_3 : store_local(doubleType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 case Bytecodes::_astore_0 : store_local(objectType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 case Bytecodes::_astore_1 : store_local(objectType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 case Bytecodes::_astore_2 : store_local(objectType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 case Bytecodes::_astore_3 : store_local(objectType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 case Bytecodes::_iastore : store_indexed(T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 case Bytecodes::_lastore : store_indexed(T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 case Bytecodes::_fastore : store_indexed(T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 case Bytecodes::_dastore : store_indexed(T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 case Bytecodes::_aastore : store_indexed(T_OBJECT); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 case Bytecodes::_bastore : store_indexed(T_BYTE ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 case Bytecodes::_castore : store_indexed(T_CHAR ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 case Bytecodes::_sastore : store_indexed(T_SHORT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 case Bytecodes::_pop : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 case Bytecodes::_pop2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 case Bytecodes::_dup : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 case Bytecodes::_dup_x1 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 case Bytecodes::_dup_x2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 case Bytecodes::_dup2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 case Bytecodes::_dup2_x1 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 case Bytecodes::_dup2_x2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 case Bytecodes::_swap : stack_op(code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 case Bytecodes::_iadd : arithmetic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 case Bytecodes::_ladd : arithmetic_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 case Bytecodes::_fadd : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 case Bytecodes::_dadd : arithmetic_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 case Bytecodes::_isub : arithmetic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 case Bytecodes::_lsub : arithmetic_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 case Bytecodes::_fsub : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 case Bytecodes::_dsub : arithmetic_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 case Bytecodes::_imul : arithmetic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 case Bytecodes::_lmul : arithmetic_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 case Bytecodes::_fmul : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 case Bytecodes::_dmul : arithmetic_op(doubleType, code); break;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2449 case Bytecodes::_idiv : arithmetic_op(intType , code, copy_state_for_exception()); break;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2450 case Bytecodes::_ldiv : arithmetic_op(longType , code, copy_state_for_exception()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 case Bytecodes::_fdiv : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 case Bytecodes::_ddiv : arithmetic_op(doubleType, code); break;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2453 case Bytecodes::_irem : arithmetic_op(intType , code, copy_state_for_exception()); break;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2454 case Bytecodes::_lrem : arithmetic_op(longType , code, copy_state_for_exception()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 case Bytecodes::_frem : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 case Bytecodes::_drem : arithmetic_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 case Bytecodes::_ineg : negate_op(intType ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 case Bytecodes::_lneg : negate_op(longType ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 case Bytecodes::_fneg : negate_op(floatType ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 case Bytecodes::_dneg : negate_op(doubleType); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 case Bytecodes::_ishl : shift_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 case Bytecodes::_lshl : shift_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 case Bytecodes::_ishr : shift_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 case Bytecodes::_lshr : shift_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 case Bytecodes::_iushr : shift_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 case Bytecodes::_lushr : shift_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 case Bytecodes::_iand : logic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 case Bytecodes::_land : logic_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 case Bytecodes::_ior : logic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 case Bytecodes::_lor : logic_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 case Bytecodes::_ixor : logic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 case Bytecodes::_lxor : logic_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 case Bytecodes::_iinc : increment(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 case Bytecodes::_i2l : convert(code, T_INT , T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 case Bytecodes::_i2f : convert(code, T_INT , T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 case Bytecodes::_i2d : convert(code, T_INT , T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 case Bytecodes::_l2i : convert(code, T_LONG , T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 case Bytecodes::_l2f : convert(code, T_LONG , T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 case Bytecodes::_l2d : convert(code, T_LONG , T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 case Bytecodes::_f2i : convert(code, T_FLOAT , T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 case Bytecodes::_f2l : convert(code, T_FLOAT , T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 case Bytecodes::_f2d : convert(code, T_FLOAT , T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 case Bytecodes::_d2i : convert(code, T_DOUBLE, T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 case Bytecodes::_d2l : convert(code, T_DOUBLE, T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 case Bytecodes::_d2f : convert(code, T_DOUBLE, T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 case Bytecodes::_i2b : convert(code, T_INT , T_BYTE ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 case Bytecodes::_i2c : convert(code, T_INT , T_CHAR ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 case Bytecodes::_i2s : convert(code, T_INT , T_SHORT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 case Bytecodes::_lcmp : compare_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 case Bytecodes::_fcmpl : compare_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 case Bytecodes::_fcmpg : compare_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 case Bytecodes::_dcmpl : compare_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 case Bytecodes::_dcmpg : compare_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 case Bytecodes::_ifeq : if_zero(intType , If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 case Bytecodes::_ifne : if_zero(intType , If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 case Bytecodes::_iflt : if_zero(intType , If::lss); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 case Bytecodes::_ifge : if_zero(intType , If::geq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 case Bytecodes::_ifgt : if_zero(intType , If::gtr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 case Bytecodes::_ifle : if_zero(intType , If::leq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 case Bytecodes::_if_icmpeq : if_same(intType , If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 case Bytecodes::_if_icmpne : if_same(intType , If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 case Bytecodes::_if_icmplt : if_same(intType , If::lss); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 case Bytecodes::_if_icmpge : if_same(intType , If::geq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 case Bytecodes::_if_icmpgt : if_same(intType , If::gtr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 case Bytecodes::_if_icmple : if_same(intType , If::leq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 case Bytecodes::_if_acmpeq : if_same(objectType, If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 case Bytecodes::_if_acmpne : if_same(objectType, If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 case Bytecodes::_goto : _goto(s.cur_bci(), s.get_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 case Bytecodes::_jsr : jsr(s.get_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 case Bytecodes::_ret : ret(s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 case Bytecodes::_tableswitch : table_switch(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 case Bytecodes::_lookupswitch : lookup_switch(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 case Bytecodes::_ireturn : method_return(ipop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 case Bytecodes::_lreturn : method_return(lpop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 case Bytecodes::_freturn : method_return(fpop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 case Bytecodes::_dreturn : method_return(dpop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 case Bytecodes::_areturn : method_return(apop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 case Bytecodes::_return : method_return(NULL ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 case Bytecodes::_getstatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 case Bytecodes::_putstatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 case Bytecodes::_getfield : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 case Bytecodes::_putfield : access_field(code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 case Bytecodes::_invokevirtual : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 case Bytecodes::_invokespecial : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 case Bytecodes::_invokestatic : // fall through
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 470
diff changeset
2526 case Bytecodes::_invokedynamic : // fall through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 case Bytecodes::_invokeinterface: invoke(code); break;
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1540
diff changeset
2528 case Bytecodes::_new : new_instance(s.get_index_u2()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 case Bytecodes::_newarray : new_type_array(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 case Bytecodes::_anewarray : new_object_array(); break;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2531 case Bytecodes::_arraylength : { ValueStack* state_before = copy_state_for_exception(); ipush(append(new ArrayLength(apop(), state_before))); break; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 case Bytecodes::_athrow : throw_op(s.cur_bci()); break;
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1540
diff changeset
2533 case Bytecodes::_checkcast : check_cast(s.get_index_u2()); break;
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1540
diff changeset
2534 case Bytecodes::_instanceof : instance_of(s.get_index_u2()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 case Bytecodes::_monitorenter : monitorenter(apop(), s.cur_bci()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 case Bytecodes::_monitorexit : monitorexit (apop(), s.cur_bci()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 case Bytecodes::_wide : ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 case Bytecodes::_multianewarray : new_multi_array(s.cur_bcp()[3]); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 case Bytecodes::_ifnull : if_null(objectType, If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 case Bytecodes::_ifnonnull : if_null(objectType, If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 case Bytecodes::_goto_w : _goto(s.cur_bci(), s.get_far_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 case Bytecodes::_jsr_w : jsr(s.get_far_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 case Bytecodes::_breakpoint : BAILOUT_("concurrent setting of breakpoint", NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 default : ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // save current bci to setup Goto at the end
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 prev_bci = s.cur_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 CHECK_BAILOUT_(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 // stop processing of this block (see try_inline_full)
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 if (_skip_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 _skip_block = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 assert(_last && _last->as_BlockEnd(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 return _last->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 // if there are any, check if last instruction is a BlockEnd instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 BlockEnd* end = last()->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 if (end == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 // all blocks must end with a BlockEnd instruction => add a Goto
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 end = new Goto(block_at(s.cur_bci()), false);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2561 append(end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 assert(end == last()->as_BlockEnd(), "inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2564
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2565 assert(end->state() != NULL, "state must already be present");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2566 assert(end->as_Return() == NULL || end->as_Throw() == NULL || end->state()->stack_size() == 0, "stack not needed for return and throw");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2567
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 // connect to begin & set state
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 // NOTE that inlining may have changed the block we are parsing
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 block()->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 // propagate state
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 for (int i = end->number_of_sux() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 BlockBegin* sux = end->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 assert(sux->is_predecessor(block()), "predecessor missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 // be careful, bailout if bytecodes are strange
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2576 if (!sux->try_merge(end->state())) BAILOUT_("block join failed", NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 scope_data()->add_to_work_list(end->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2579
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2581
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 // done
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 return end;
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2585
a61af66fc99e Initial load
duke
parents:
diff changeset
2586
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 if (start_in_current_block_for_inlining && !bailed_out()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 iterate_bytecodes_for_block(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 start_in_current_block_for_inlining = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 BlockBegin* b;
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 while ((b = scope_data()->remove_from_work_list()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 if (!b->is_set(BlockBegin::was_visited_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 if (b->is_set(BlockBegin::osr_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 // we're about to parse the osr entry block, so make sure
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 // we setup the OSR edge leading into this block so that
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 // Phis get setup correctly.
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 setup_osr_entry_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 // this is no longer the osr entry block, so clear it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 b->clear(BlockBegin::osr_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 b->set(BlockBegin::was_visited_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 connect_to_end(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 } while (!bailed_out() && !scope_data()->is_work_list_empty());
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2611
a61af66fc99e Initial load
duke
parents:
diff changeset
2612
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 bool GraphBuilder::_can_trap [Bytecodes::number_of_java_codes];
a61af66fc99e Initial load
duke
parents:
diff changeset
2614
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 void GraphBuilder::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 // the following bytecodes are assumed to potentially
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 // throw exceptions in compiled code - note that e.g.
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 // monitorexit & the return bytecodes do not throw
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 // exceptions since monitor pairing proved that they
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 // succeed (if monitor pairing succeeded)
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 Bytecodes::Code can_trap_list[] =
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 { Bytecodes::_ldc
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 , Bytecodes::_ldc_w
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 , Bytecodes::_ldc2_w
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 , Bytecodes::_iaload
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 , Bytecodes::_laload
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 , Bytecodes::_faload
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 , Bytecodes::_daload
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 , Bytecodes::_aaload
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 , Bytecodes::_baload
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 , Bytecodes::_caload
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 , Bytecodes::_saload
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 , Bytecodes::_iastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 , Bytecodes::_lastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 , Bytecodes::_fastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 , Bytecodes::_dastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 , Bytecodes::_aastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 , Bytecodes::_bastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 , Bytecodes::_castore
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 , Bytecodes::_sastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 , Bytecodes::_idiv
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 , Bytecodes::_ldiv
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 , Bytecodes::_irem
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 , Bytecodes::_lrem
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 , Bytecodes::_getstatic
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 , Bytecodes::_putstatic
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 , Bytecodes::_getfield
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 , Bytecodes::_putfield
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 , Bytecodes::_invokevirtual
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 , Bytecodes::_invokespecial
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 , Bytecodes::_invokestatic
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 470
diff changeset
2652 , Bytecodes::_invokedynamic
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 , Bytecodes::_invokeinterface
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 , Bytecodes::_new
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 , Bytecodes::_newarray
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 , Bytecodes::_anewarray
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 , Bytecodes::_arraylength
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 , Bytecodes::_athrow
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 , Bytecodes::_checkcast
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 , Bytecodes::_instanceof
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 , Bytecodes::_monitorenter
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 , Bytecodes::_multianewarray
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2664
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 // inititialize trap tables
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 for (int i = 0; i < Bytecodes::number_of_java_codes; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 _can_trap[i] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 // set standard trap info
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 for (uint j = 0; j < ARRAY_SIZE(can_trap_list); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 _can_trap[can_trap_list[j]] = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2674
a61af66fc99e Initial load
duke
parents:
diff changeset
2675
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 BlockBegin* GraphBuilder::header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 assert(entry->is_set(f), "entry/flag mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 // create header block
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 BlockBegin* h = new BlockBegin(entry->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 h->set_depth_first_number(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2681
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 Value l = h;
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 BlockEnd* g = new Goto(entry, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 l->set_next(g, entry->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 h->set_end(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 h->set(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 // setup header block end state
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2688 ValueStack* s = state->copy(ValueStack::StateAfter, entry->bci()); // can use copy since stack is empty (=> no phis)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 assert(s->stack_is_empty(), "must have empty stack at entry point");
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 g->set_state(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 return h;
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2693
a61af66fc99e Initial load
duke
parents:
diff changeset
2694
a61af66fc99e Initial load
duke
parents:
diff changeset
2695
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 BlockBegin* GraphBuilder::setup_start_block(int osr_bci, BlockBegin* std_entry, BlockBegin* osr_entry, ValueStack* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 BlockBegin* start = new BlockBegin(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2698
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 // This code eliminates the empty start block at the beginning of
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 // each method. Previously, each method started with the
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 // start-block created below, and this block was followed by the
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // header block that was always empty. This header block is only
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 // necesary if std_entry is also a backward branch target because
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // then phi functions may be necessary in the header block. It's
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 // also necessary when profiling so that there's a single block that
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 // can increment the interpreter_invocation_count.
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 BlockBegin* new_header_block;
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2708 if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2709 new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2710 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 new_header_block = std_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 // setup start block (root for the IR graph)
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 Base* base =
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 new Base(
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 new_header_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 osr_entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 start->set_next(base, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 start->set_end(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 // create & setup state for start block
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2723 start->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2724 base->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2725
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 if (base->std_entry()->state() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 // setup states for header blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 base->std_entry()->merge(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 assert(base->std_entry()->state() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2734
a61af66fc99e Initial load
duke
parents:
diff changeset
2735
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 void GraphBuilder::setup_osr_entry_block() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 assert(compilation()->is_osr_compile(), "only for osrs");
a61af66fc99e Initial load
duke
parents:
diff changeset
2738
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 int osr_bci = compilation()->osr_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 ciBytecodeStream s(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 s.reset_to_bci(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 s.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 scope_data()->set_stream(&s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2744
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // create a new block to be the osr setup code
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 _osr_entry = new BlockBegin(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 _osr_entry->set(BlockBegin::osr_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 _osr_entry->set_depth_first_number(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 BlockBegin* target = bci2block()->at(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 assert(target != NULL && target->is_set(BlockBegin::osr_entry_flag), "must be there");
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 // the osr entry has no values for locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 ValueStack* state = target->state()->copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 _osr_entry->set_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2754
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 _block = _osr_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 _state = _osr_entry->state()->copy();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2758 assert(_state->bci() == osr_bci, "mismatch");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 _last = _osr_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 Value e = append(new OsrEntry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 e->set_needs_null_check(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2762
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 // OSR buffer is
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 // locals[nlocals-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 // monitors[number_of_locks-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 // locals is a direct copy of the interpreter frame so in the osr buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 // so first slot in the local array is the last local from the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 // and last slot is local[0] (receiver) from the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 // Similarly with locks. The first lock slot in the osr buffer is the nth lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 // in the interpreter frame (the method lock if a sync method)
a61af66fc99e Initial load
duke
parents:
diff changeset
2775
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // Initialize monitors in the compiled activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2777
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 Value local;
a61af66fc99e Initial load
duke
parents:
diff changeset
2780
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 // find all the locals that the interpreter thinks contain live oops
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 const BitMap live_oops = method()->live_local_oops_at_bci(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2783
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 // compute the offset into the locals so that we can treat the buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 // as if the locals were still in the interpreter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 int locals_offset = BytesPerWord * (method()->max_locals() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 for_each_local_value(state, index, local) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 int offset = locals_offset - (index + local->type()->size() - 1) * BytesPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 Value get;
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 if (local->type()->is_object_kind() && !live_oops.at(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 // The interpreter thinks this local is dead but the compiler
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 // doesn't so pretend that the interpreter passed in null.
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 get = append(new Constant(objectNull));
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 get = append(new UnsafeGetRaw(as_BasicType(local->type()), e,
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 append(new Constant(new IntConstant(offset))),
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 0,
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2798 true /*unaligned*/, true /*wide*/));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 _state->store_local(index, get);
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2802
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 // the storage for the OSR buffer is freed manually in the LIRGenerator.
a61af66fc99e Initial load
duke
parents:
diff changeset
2804
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 assert(state->caller_state() == NULL, "should be top scope");
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 state->clear_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 Goto* g = new Goto(target, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 append(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 _osr_entry->set_end(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 target->merge(_osr_entry->end()->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2811
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2814
a61af66fc99e Initial load
duke
parents:
diff changeset
2815
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 ValueStack* GraphBuilder::state_at_entry() {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2817 ValueStack* state = new ValueStack(scope(), NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2818
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 // Set up locals for receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 int idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 if (!method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 // we should always see the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 state->store_local(idx, new Local(objectType, idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 idx = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2826
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 // Set up locals for incoming arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 ciSignature* sig = method()->signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 for (int i = 0; i < sig->count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 ciType* type = sig->type_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 BasicType basic_type = type->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 // don't allow T_ARRAY to propagate into locals types
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 if (basic_type == T_ARRAY) basic_type = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 ValueType* vt = as_ValueType(basic_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 state->store_local(idx, new Local(vt, idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 idx += type->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2838
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 // lock synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 if (method()->is_synchronized()) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2841 state->lock(NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2843
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 return state;
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2846
a61af66fc99e Initial load
duke
parents:
diff changeset
2847
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 : _scope_data(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 , _instruction_count(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 , _osr_entry(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 , _memory(new MemoryBuffer())
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 , _compilation(compilation)
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 , _inline_bailout_msg(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 int osr_bci = compilation->osr_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
2857
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // determine entry points and bci2block mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 BlockListBuilder blm(compilation, scope, osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
2861
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 BlockList* bci2block = blm.bci2block();
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 BlockBegin* start_block = bci2block->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2864
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 push_root_scope(scope, bci2block, start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2866
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 // setup state for std entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 _initial_state = state_at_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 start_block->merge(_initial_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2870
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 // complete graph
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 _vmap = new ValueMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 switch (scope->method()->intrinsic_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 case vmIntrinsics::_dabs : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 case vmIntrinsics::_dsqrt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 case vmIntrinsics::_dsin : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 case vmIntrinsics::_dcos : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 case vmIntrinsics::_dtan : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 case vmIntrinsics::_dlog : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 case vmIntrinsics::_dlog10 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 // Compiles where the root method is an intrinsic need a special
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 // compilation environment because the bytecodes for the method
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 // shouldn't be parsed during the compilation, only the special
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 // Intrinsic node should be emitted. If this isn't done the the
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 // code for the inlined version will be different than the root
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 // compiled version which could lead to monotonicity problems on
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 // intel.
a61af66fc99e Initial load
duke
parents:
diff changeset
2889
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 // Set up a stream so that appending instructions works properly.
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 ciBytecodeStream s(scope->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 s.reset_to_bci(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 scope_data()->set_stream(&s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 s.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2895
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 // setup the initial block state
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 _block = start_block;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2898 _state = start_block->state()->copy_for_parsing();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 _last = start_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 load_local(doubleType, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2901
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 // Emit the intrinsic node.
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 bool result = try_inline_intrinsics(scope->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 if (!result) BAILOUT("failed to inline intrinsic");
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 method_return(dpop());
a61af66fc99e Initial load
duke
parents:
diff changeset
2906
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 // connect the begin and end blocks and we're all done.
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 BlockEnd* end = last()->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 block()->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 scope_data()->add_to_work_list(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 iterate_all_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
2918
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 _start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2920
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 eliminate_redundant_phis(_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
2922
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 NOT_PRODUCT(if (PrintValueNumbering && Verbose) print_stats());
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 // for osr compile, bailout if some requirements are not fulfilled
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 if (osr_bci != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 BlockBegin* osr_block = blm.bci2block()->at(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 assert(osr_block->is_set(BlockBegin::was_visited_flag),"osr entry must have been visited for osr compile");
a61af66fc99e Initial load
duke
parents:
diff changeset
2928
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 // check if osr entry point has empty stack - we cannot handle non-empty stacks at osr entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 if (!osr_block->state()->stack_is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 BAILOUT("stack not empty at OSR entry point");
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 if (PrintCompilation && Verbose) tty->print_cr("Created %d Instructions", _instruction_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2938
a61af66fc99e Initial load
duke
parents:
diff changeset
2939
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2940 ValueStack* GraphBuilder::copy_state_before() {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2941 return copy_state_before_with_bci(bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2942 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2943
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2944 ValueStack* GraphBuilder::copy_state_exhandling() {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2945 return copy_state_exhandling_with_bci(bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2946 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2947
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2948 ValueStack* GraphBuilder::copy_state_for_exception() {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2949 return copy_state_for_exception_with_bci(bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2950 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2951
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2952 ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2953 return state()->copy(ValueStack::StateBefore, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2955
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2956 ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2957 if (!has_handler()) return NULL;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2958 return state()->copy(ValueStack::StateBefore, bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2959 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2960
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2961 ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2962 ValueStack* s = copy_state_exhandling_with_bci(bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2963 if (s == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2964 if (_compilation->env()->jvmti_can_access_local_variables()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2965 s = state()->copy(ValueStack::ExceptionState, bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2966 } else {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2967 s = state()->copy(ValueStack::EmptyExceptionState, bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2968 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2969 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2970 return s;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2971 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2972
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 int recur_level = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 for (IRScope* s = scope(); s != NULL; s = s->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 if (s->method() == cur_callee) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 ++recur_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 return recur_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2982
a61af66fc99e Initial load
duke
parents:
diff changeset
2983
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 // Clear out any existing inline bailout condition
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 clear_inline_bailout();
a61af66fc99e Initial load
duke
parents:
diff changeset
2987
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 if (callee->should_exclude()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 // callee is excluded
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 INLINE_BAILOUT("excluded by CompilerOracle")
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 } else if (!callee->can_be_compiled()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 // callee is not compilable (prob. has breakpoints)
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 INLINE_BAILOUT("not compilable")
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 // intrinsics can be native or not
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 } else if (callee->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 // non-intrinsic natives cannot be inlined
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 INLINE_BAILOUT("non-intrinsic native")
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 } else if (callee->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 INLINE_BAILOUT("abstract")
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 return try_inline_full(callee, holder_known);
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3006
a61af66fc99e Initial load
duke
parents:
diff changeset
3007
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 if (!InlineNatives ) INLINE_BAILOUT("intrinsic method inlining disabled");
1540
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3010 if (callee->is_synchronized()) {
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3011 // We don't currently support any synchronized intrinsics
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3012 return false;
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3013 }
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3014
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 // callee seems like a good candidate
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 // determine id
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 bool preserves_state = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 bool cantrap = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 vmIntrinsics::ID id = callee->intrinsic_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 switch (id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 case vmIntrinsics::_arraycopy :
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 if (!InlineArrayCopy) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3024
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 case vmIntrinsics::_currentTimeMillis:
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 case vmIntrinsics::_nanoTime:
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3030
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 case vmIntrinsics::_floatToRawIntBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 case vmIntrinsics::_intBitsToFloat :
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 case vmIntrinsics::_doubleToRawLongBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 case vmIntrinsics::_longBitsToDouble :
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 if (!InlineMathNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3039
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 case vmIntrinsics::_getClass :
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 if (!InlineClassNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3044
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 case vmIntrinsics::_currentThread :
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 if (!InlineThreadNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3050
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 case vmIntrinsics::_dabs : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 case vmIntrinsics::_dsqrt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 case vmIntrinsics::_dsin : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 case vmIntrinsics::_dcos : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 case vmIntrinsics::_dtan : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 case vmIntrinsics::_dlog : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 case vmIntrinsics::_dlog10 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 if (!InlineMathNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3062
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 // sun/misc/AtomicLong.attemptUpdate
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 case vmIntrinsics::_attemptUpdate :
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 if (!VM_Version::supports_cx8()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 if (!InlineAtomicLong) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3069
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 // Use special nodes for Unsafe instructions so we can more easily
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 // perform an address-mode optimization on the raw variants
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 case vmIntrinsics::_getObject : return append_unsafe_get_obj(callee, T_OBJECT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 case vmIntrinsics::_getBoolean: return append_unsafe_get_obj(callee, T_BOOLEAN, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 case vmIntrinsics::_getByte : return append_unsafe_get_obj(callee, T_BYTE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 case vmIntrinsics::_getShort : return append_unsafe_get_obj(callee, T_SHORT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 case vmIntrinsics::_getChar : return append_unsafe_get_obj(callee, T_CHAR, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 case vmIntrinsics::_getInt : return append_unsafe_get_obj(callee, T_INT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 case vmIntrinsics::_getLong : return append_unsafe_get_obj(callee, T_LONG, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 case vmIntrinsics::_getFloat : return append_unsafe_get_obj(callee, T_FLOAT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 case vmIntrinsics::_getDouble : return append_unsafe_get_obj(callee, T_DOUBLE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3081
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 case vmIntrinsics::_putObject : return append_unsafe_put_obj(callee, T_OBJECT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 case vmIntrinsics::_putBoolean: return append_unsafe_put_obj(callee, T_BOOLEAN, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 case vmIntrinsics::_putByte : return append_unsafe_put_obj(callee, T_BYTE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 case vmIntrinsics::_putShort : return append_unsafe_put_obj(callee, T_SHORT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 case vmIntrinsics::_putChar : return append_unsafe_put_obj(callee, T_CHAR, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 case vmIntrinsics::_putInt : return append_unsafe_put_obj(callee, T_INT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 case vmIntrinsics::_putLong : return append_unsafe_put_obj(callee, T_LONG, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 case vmIntrinsics::_putFloat : return append_unsafe_put_obj(callee, T_FLOAT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 case vmIntrinsics::_putDouble : return append_unsafe_put_obj(callee, T_DOUBLE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3091
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 case vmIntrinsics::_getObjectVolatile : return append_unsafe_get_obj(callee, T_OBJECT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 case vmIntrinsics::_getBooleanVolatile: return append_unsafe_get_obj(callee, T_BOOLEAN, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 case vmIntrinsics::_getByteVolatile : return append_unsafe_get_obj(callee, T_BYTE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 case vmIntrinsics::_getShortVolatile : return append_unsafe_get_obj(callee, T_SHORT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 case vmIntrinsics::_getCharVolatile : return append_unsafe_get_obj(callee, T_CHAR, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 case vmIntrinsics::_getIntVolatile : return append_unsafe_get_obj(callee, T_INT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 case vmIntrinsics::_getLongVolatile : return append_unsafe_get_obj(callee, T_LONG, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 case vmIntrinsics::_getFloatVolatile : return append_unsafe_get_obj(callee, T_FLOAT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 case vmIntrinsics::_getDoubleVolatile : return append_unsafe_get_obj(callee, T_DOUBLE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3101
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 case vmIntrinsics::_putObjectVolatile : return append_unsafe_put_obj(callee, T_OBJECT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 case vmIntrinsics::_putBooleanVolatile: return append_unsafe_put_obj(callee, T_BOOLEAN, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 case vmIntrinsics::_putByteVolatile : return append_unsafe_put_obj(callee, T_BYTE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 case vmIntrinsics::_putShortVolatile : return append_unsafe_put_obj(callee, T_SHORT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 case vmIntrinsics::_putCharVolatile : return append_unsafe_put_obj(callee, T_CHAR, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 case vmIntrinsics::_putIntVolatile : return append_unsafe_put_obj(callee, T_INT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 case vmIntrinsics::_putLongVolatile : return append_unsafe_put_obj(callee, T_LONG, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 case vmIntrinsics::_putFloatVolatile : return append_unsafe_put_obj(callee, T_FLOAT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 case vmIntrinsics::_putDoubleVolatile : return append_unsafe_put_obj(callee, T_DOUBLE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3111
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 case vmIntrinsics::_getByte_raw : return append_unsafe_get_raw(callee, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 case vmIntrinsics::_getShort_raw : return append_unsafe_get_raw(callee, T_SHORT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 case vmIntrinsics::_getChar_raw : return append_unsafe_get_raw(callee, T_CHAR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 case vmIntrinsics::_getInt_raw : return append_unsafe_get_raw(callee, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 case vmIntrinsics::_getLong_raw : return append_unsafe_get_raw(callee, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 case vmIntrinsics::_getFloat_raw : return append_unsafe_get_raw(callee, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 case vmIntrinsics::_getDouble_raw : return append_unsafe_get_raw(callee, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 case vmIntrinsics::_putByte_raw : return append_unsafe_put_raw(callee, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 case vmIntrinsics::_putShort_raw : return append_unsafe_put_raw(callee, T_SHORT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 case vmIntrinsics::_putChar_raw : return append_unsafe_put_raw(callee, T_CHAR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 case vmIntrinsics::_putInt_raw : return append_unsafe_put_raw(callee, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 case vmIntrinsics::_putLong_raw : return append_unsafe_put_raw(callee, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 case vmIntrinsics::_putFloat_raw : return append_unsafe_put_raw(callee, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 case vmIntrinsics::_putDouble_raw : return append_unsafe_put_raw(callee, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3127
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 case vmIntrinsics::_prefetchRead : return append_unsafe_prefetch(callee, false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 case vmIntrinsics::_prefetchWrite : return append_unsafe_prefetch(callee, false, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 case vmIntrinsics::_prefetchReadStatic : return append_unsafe_prefetch(callee, true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 case vmIntrinsics::_prefetchWriteStatic : return append_unsafe_prefetch(callee, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3132
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 case vmIntrinsics::_checkIndex :
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 if (!InlineNIOCheckIndex) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 case vmIntrinsics::_putOrderedObject : return append_unsafe_put_obj(callee, T_OBJECT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 case vmIntrinsics::_putOrderedInt : return append_unsafe_put_obj(callee, T_INT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 case vmIntrinsics::_putOrderedLong : return append_unsafe_put_obj(callee, T_LONG, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3140
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 case vmIntrinsics::_compareAndSwapLong:
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 if (!VM_Version::supports_cx8()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 case vmIntrinsics::_compareAndSwapInt:
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 case vmIntrinsics::_compareAndSwapObject:
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 append_unsafe_CAS(callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3148
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 default : return false; // do not inline
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 // create intrinsic node
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 const bool has_receiver = !callee->is_static();
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 ValueType* result_type = as_ValueType(callee->return_type());
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3154 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3155
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 Values* args = state()->pop_arguments(callee->arg_size());
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3157
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3158 if (is_profiling()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 // Don't profile in the special case where the root method
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 // is the intrinsic
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 if (callee != method()) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3162 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3163 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3164 if (profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3165 Value recv = NULL;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3166 if (has_receiver) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3167 recv = args->at(0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3168 null_check(recv);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3169 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3170 profile_call(recv, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3174
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3175 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 preserves_state, cantrap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 // append instruction & push result
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 Value value = append_split(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 if (result_type != voidType) push(result_type, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
3180
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 // printing
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 if (PrintInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 print_inline_result(callee, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3187
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 // done
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3191
a61af66fc99e Initial load
duke
parents:
diff changeset
3192
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 // Introduce a new callee continuation point - all Ret instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 // will be replaced with Gotos to this point.
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 BlockBegin* cont = block_at(next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr");
a61af66fc99e Initial load
duke
parents:
diff changeset
3198
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 // Note: can not assign state to continuation yet, as we have to
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 // pick up the state from the Ret instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
3201
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 // Push callee scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 push_scope_for_jsr(cont, jsr_dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3204
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 // Temporarily set up bytecode stream so we can append instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 // (only using the bci of this stream)
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 scope_data()->set_stream(scope_data()->parent()->stream());
a61af66fc99e Initial load
duke
parents:
diff changeset
3208
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 BlockBegin* jsr_start_block = block_at(jsr_dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 assert(jsr_start_block != NULL, "jsr start block must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 assert(!jsr_start_block->is_set(BlockBegin::was_visited_flag), "should not have visited jsr yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 Goto* goto_sub = new Goto(jsr_start_block, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 // Must copy state to avoid wrong sharing when parsing bytecodes
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 assert(jsr_start_block->state() == NULL, "should have fresh jsr starting block");
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3215 jsr_start_block->set_state(copy_state_before_with_bci(jsr_dest_bci));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 append(goto_sub);
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 _block->set_end(goto_sub);
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 _last = _block = jsr_start_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3219
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 // Clear out bytecode stream
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3222
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 scope_data()->add_to_work_list(jsr_start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3224
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 // Ready to resume parsing in subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 iterate_all_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3227
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 // If we bailed out during parsing, return immediately (this is bad news)
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 CHECK_BAILOUT_(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3230
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 // Detect whether the continuation can actually be reached. If not,
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 // it has not had state set by the join() operations in
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 // iterate_bytecodes_for_block()/ret() and we should not touch the
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 // iteration state. The calling activation of
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 // iterate_bytecodes_for_block will then complete normally.
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 if (cont->state() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 if (!cont->is_set(BlockBegin::was_visited_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 // add continuation to work list instead of parsing it immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 scope_data()->parent()->add_to_work_list(cont);
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3242
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 assert(jsr_continuation() == cont, "continuation must not have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 assert(!jsr_continuation()->is_set(BlockBegin::was_visited_flag) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 jsr_continuation()->is_set(BlockBegin::parser_loop_header_flag),
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 "continuation can only be visited in case of backward branches");
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 assert(_last && _last->as_BlockEnd(), "block must have end");
a61af66fc99e Initial load
duke
parents:
diff changeset
3248
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 // continuation is in work list, so end iteration of current block
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 _skip_block = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 pop_scope_for_jsr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3252
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3255
a61af66fc99e Initial load
duke
parents:
diff changeset
3256
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 // Inline the entry of a synchronized method as a monitor enter and
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 // register the exception handler which releases the monitor if an
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 // exception is thrown within the callee. Note that the monitor enter
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 // cannot throw an exception itself, because the receiver is
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 // guaranteed to be non-null by the explicit null check at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 // beginning of inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 void GraphBuilder::inline_sync_entry(Value lock, BlockBegin* sync_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 assert(lock != NULL && sync_handler != NULL, "lock or handler missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
3265
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 monitorenter(lock, SynchronizationEntryBCI);
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 assert(_last->as_MonitorEnter() != NULL, "monitor enter expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 _last->set_needs_null_check(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3269
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 sync_handler->set(BlockBegin::exception_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 sync_handler->set(BlockBegin::is_on_work_list_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3272
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 XHandler* h = new XHandler(desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 h->set_entry_block(sync_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 scope_data()->xhandlers()->append(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 scope_data()->set_has_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3279
a61af66fc99e Initial load
duke
parents:
diff changeset
3280
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 // If an exception is thrown and not handled within an inlined
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 // synchronized method, the monitor must be released before the
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 // exception is rethrown in the outer scope. Generate the appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 // instructions here.
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 BlockBegin* orig_block = _block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 ValueStack* orig_state = _state;
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 Instruction* orig_last = _last;
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 _last = _block = sync_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 _state = sync_handler->state()->copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
3291
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 assert(sync_handler != NULL, "handler missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 assert(!sync_handler->is_set(BlockBegin::was_visited_flag), "is visited here");
a61af66fc99e Initial load
duke
parents:
diff changeset
3294
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 assert(lock != NULL || default_handler, "lock or handler missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
3296
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 XHandler* h = scope_data()->xhandlers()->remove_last();
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 assert(h->entry_block() == sync_handler, "corrupt list of handlers");
a61af66fc99e Initial load
duke
parents:
diff changeset
3299
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 block()->set(BlockBegin::was_visited_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 assert(exception->is_pinned(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
3303
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 int bci = SynchronizationEntryBCI;
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 if (lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing");
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3307 if (!lock->is_linked()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 lock = append_with_bci(lock, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3310
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 // exit the monitor in the context of the synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 monitorexit(lock, SynchronizationEntryBCI);
a61af66fc99e Initial load
duke
parents:
diff changeset
3313
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 // exit the context of the synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 if (!default_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 pop_scope();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3317 bci = _state->caller_state()->bci();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3318 _state = _state->caller_state()->copy_for_parsing();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3321
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 // perform the throw as if at the the call site
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 apush(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 throw_op(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3325
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 BlockEnd* end = last()->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 block()->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
3328
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 _block = orig_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 _state = orig_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 _last = orig_last;
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3333
a61af66fc99e Initial load
duke
parents:
diff changeset
3334
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 assert(!callee->is_native(), "callee must not be native");
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3337 if (count_backedges() && callee->has_loops()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3338 INLINE_BAILOUT("too complex for tiered");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3339 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 // first perform tests of things it's not possible to inline
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 if (callee->has_exception_handlers() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 if (callee->is_synchronized() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 !InlineSynchronizedMethods ) INLINE_BAILOUT("callee is synchronized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 if (!callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 if (!callee->has_balanced_monitors()) INLINE_BAILOUT("callee's monitors do not match");
a61af66fc99e Initial load
duke
parents:
diff changeset
3347
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 // Proper inlining of methods with jsrs requires a little more work.
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
3350
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 // now perform tests that are based on flag settings
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining");
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 if (callee->code_size() > max_inline_size() ) INLINE_BAILOUT("callee is too large");
a61af66fc99e Initial load
duke
parents:
diff changeset
3355
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 // don't inline throwable methods unless the inlining tree is rooted in a throwable class
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 if (callee->name() == ciSymbol::object_initializer_name() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 callee->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 // Throwable constructor call
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 IRScope* top = scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 while (top->caller() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 top = top->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 if (!top->method()->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 INLINE_BAILOUT("don't inline Throwable constructors");
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3368
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 // When SSE2 is used on intel, then no special handling is needed
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 // for strictfp because the enum-constant is fixed at compile time,
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 // the check for UseSSE2 is needed here
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 if (strict_fp_requires_explicit_rounding && UseSSE < 2 && method()->is_strict() != callee->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 INLINE_BAILOUT("caller and callee have different strict fp requirements");
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3375
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3379
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3380 if (is_profiling() && !callee->ensure_method_data()) {
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3381 INLINE_BAILOUT("mdo allocation failed");
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3382 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 // printing
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 if (PrintInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 print_inline_result(callee, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3389
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 // NOTE: Bailouts from this point on, which occur at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 // GraphBuilder level, do not cause bailout just of the inlining but
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 // in fact of the entire compilation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3393
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 BlockBegin* orig_block = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
3395
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 const int args_base = state()->stack_size() - callee->arg_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 assert(args_base >= 0, "stack underflow during inlining");
a61af66fc99e Initial load
duke
parents:
diff changeset
3398
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 // Insert null check if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 Value recv = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 if (code() != Bytecodes::_invokestatic) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 // note: null check must happen even if first instruction of callee does
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 // an implicit null check since the callee is in a different scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 // and we must make sure exception handling does the right thing
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 assert(!callee->is_static(), "callee must not be static");
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 assert(callee->arg_size() > 0, "must have at least a receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 recv = state()->stack_at(args_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 null_check(recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3410
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3411 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3412 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3413 // this may be redundant here...
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3414 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3415
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3416 if (profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3417 profile_call(recv, holder_known ? callee->holder() : NULL);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3418 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3419 if (profile_inlined_calls()) {
1825
80c9354976b0 6988346: 6986046 breaks tiered
iveresov
parents: 1819
diff changeset
3420 profile_invocation(callee, copy_state_before());
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3421 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3423
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 // Introduce a new callee continuation point - if the callee has
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 // more than one return instruction or the return does not allow
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 // fall-through of control flow, all return instructions of the
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 // callee will need to be replaced by Goto's pointing to this
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 // continuation point.
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 BlockBegin* cont = block_at(next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 bool continuation_existed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 if (cont == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 cont = new BlockBegin(next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 // low number so that continuation gets parsed as early as possible
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 cont->set_depth_first_number(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 if (PrintInitialBlockList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 tty->print_cr("CFG: created block %d (bci %d) as continuation for inline at bci %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 cont->block_id(), cont->bci(), bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 continuation_existed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 // Record number of predecessors of continuation block before
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 // inlining, to detect if inlined method has edges to its
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 // continuation after inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 int continuation_preds = cont->number_of_preds();
a61af66fc99e Initial load
duke
parents:
diff changeset
3447
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 // Push callee scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 push_scope(callee, cont);
a61af66fc99e Initial load
duke
parents:
diff changeset
3450
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 // the BlockListBuilder for the callee could have bailed out
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 CHECK_BAILOUT_(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3453
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 // Temporarily set up bytecode stream so we can append instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 // (only using the bci of this stream)
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 scope_data()->set_stream(scope_data()->parent()->stream());
a61af66fc99e Initial load
duke
parents:
diff changeset
3457
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 // Pass parameters into callee state: add assignments
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 // note: this will also ensure that all arguments are computed before being passed
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 ValueStack* callee_state = state();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3461 ValueStack* caller_state = state()->caller_state();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 { int i = args_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 while (i < caller_state->stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 const int par_no = i - args_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 Value arg = caller_state->stack_at_inc(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 // NOTE: take base() of arg->type() to avoid problems storing
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 // constants
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 store_local(callee_state, arg, arg->type()->base(), par_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3471
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 // Remove args from stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 // Note that we preserve locals state in case we can use it later
a61af66fc99e Initial load
duke
parents:
diff changeset
3474 // (see use of pop_scope() below)
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 caller_state->truncate_stack(args_base);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3476 assert(callee_state->stack_size() == 0, "callee stack must be empty");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3477
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 Value lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 BlockBegin* sync_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3480
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 // Inline the locking of the receiver if the callee is synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 if (callee->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror())))
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 : state()->local_at(0);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3485 sync_handler = new BlockBegin(SynchronizationEntryBCI);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 inline_sync_entry(lock, sync_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 BlockBegin* callee_start_block = block_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 if (callee_start_block != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header");
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 Goto* goto_callee = new Goto(callee_start_block, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 // The state for this goto is in the scope of the callee, so use
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 // the entry bci for the callee instead of the call site bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 append_with_bci(goto_callee, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 _block->set_end(goto_callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 callee_start_block->merge(callee_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
3499
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 _last = _block = callee_start_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3501
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 scope_data()->add_to_work_list(callee_start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3504
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 // Clear out bytecode stream
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3507
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 // Ready to resume parsing in callee (either in the same block we
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 // were in before or in the callee's start block)
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 iterate_all_blocks(callee_start_block == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3511
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 // If we bailed out during parsing, return immediately (this is bad news)
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 if (bailed_out()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3514
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // iterate_all_blocks theoretically traverses in random order; in
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 // practice, we have only traversed the continuation if we are
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 // inlining into a subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 assert(continuation_existed ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 !continuation()->is_set(BlockBegin::was_visited_flag),
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 "continuation should not have been parsed yet if we created it");
a61af66fc99e Initial load
duke
parents:
diff changeset
3521
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 // If we bailed out during parsing, return immediately (this is bad news)
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 CHECK_BAILOUT_(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3524
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 // At this point we are almost ready to return and resume parsing of
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 // the caller back in the GraphBuilder. The only thing we want to do
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 // first is an optimization: during parsing of the callee we
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 // generated at least one Goto to the continuation block. If we
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 // generated exactly one, and if the inlined method spanned exactly
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 // one block (and we didn't have to Goto its entry), then we snip
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 // off the Goto to the continuation, allowing control to fall
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 // through back into the caller block and effectively performing
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 // block merging. This allows load elimination and CSE to take place
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 // across multiple callee scopes if they are relatively simple, and
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 // is currently essential to making inlining profitable.
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 if ( num_returns() == 1
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 && block() == orig_block
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 && block() == inline_cleanup_block()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 _last = inline_cleanup_return_prev();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3540 _state = inline_cleanup_state();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 } else if (continuation_preds == cont->number_of_preds()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 // Inlining caused that the instructions after the invoke in the
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 // caller are not reachable any more. So skip filling this block
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // with instructions!
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 assert (cont == continuation(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 assert(_last && _last->as_BlockEnd(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 _skip_block = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 // Resume parsing in continuation block unless it was already parsed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 // Note that if we don't change _last here, iteration in
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 // iterate_bytecodes_for_block will stop when we return.
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 // add continuation to work list instead of parsing it immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 assert(_last && _last->as_BlockEnd(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 scope_data()->parent()->add_to_work_list(continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 _skip_block = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3559
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 // Fill the exception handler for synchronized methods with instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 if (callee->is_synchronized() && sync_handler->state() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 fill_sync_handler(lock, sync_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 pop_scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3566
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 compilation()->notice_inlined_method(callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
3568
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3571
a61af66fc99e Initial load
duke
parents:
diff changeset
3572
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 void GraphBuilder::inline_bailout(const char* msg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 assert(msg != NULL, "inline bailout msg must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 _inline_bailout_msg = msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3577
a61af66fc99e Initial load
duke
parents:
diff changeset
3578
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 void GraphBuilder::clear_inline_bailout() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 _inline_bailout_msg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3582
a61af66fc99e Initial load
duke
parents:
diff changeset
3583
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 void GraphBuilder::push_root_scope(IRScope* scope, BlockList* bci2block, BlockBegin* start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 ScopeData* data = new ScopeData(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 data->set_scope(scope);
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 data->set_bci2block(bci2block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 _scope_data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 _block = start;
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3591
a61af66fc99e Initial load
duke
parents:
diff changeset
3592
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 void GraphBuilder::push_scope(ciMethod* callee, BlockBegin* continuation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 IRScope* callee_scope = new IRScope(compilation(), scope(), bci(), callee, -1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 scope()->add_callee(callee_scope);
a61af66fc99e Initial load
duke
parents:
diff changeset
3596
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 BlockListBuilder blb(compilation(), callee_scope, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
3599
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 if (!blb.bci2block()->at(0)->is_set(BlockBegin::parser_loop_header_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 // this scope can be inlined directly into the caller so remove
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 // the block at bci 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 blb.bci2block()->at_put(0, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3605
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3606 set_state(new ValueStack(callee_scope, state()->copy(ValueStack::CallerState, bci())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3607
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 ScopeData* data = new ScopeData(scope_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 data->set_scope(callee_scope);
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 data->set_bci2block(blb.bci2block());
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 data->set_continuation(continuation);
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 _scope_data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3614
a61af66fc99e Initial load
duke
parents:
diff changeset
3615
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 void GraphBuilder::push_scope_for_jsr(BlockBegin* jsr_continuation, int jsr_dest_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 ScopeData* data = new ScopeData(scope_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 data->set_parsing_jsr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 data->set_jsr_entry_bci(jsr_dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 data->set_jsr_return_address_local(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 // Must clone bci2block list as we will be mutating it in order to
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 // properly clone all blocks in jsr region as well as exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 // handlers containing rets
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 BlockList* new_bci2block = new BlockList(bci2block()->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 new_bci2block->push_all(bci2block());
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 data->set_bci2block(new_bci2block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 data->set_scope(scope());
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 data->setup_jsr_xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 data->set_continuation(continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 data->set_jsr_continuation(jsr_continuation);
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 _scope_data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3633
a61af66fc99e Initial load
duke
parents:
diff changeset
3634
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 void GraphBuilder::pop_scope() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 int number_of_locks = scope()->number_of_locks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 _scope_data = scope_data()->parent();
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 // accumulate minimum number of monitor slots to be reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 scope()->set_min_number_of_locks(number_of_locks);
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3641
a61af66fc99e Initial load
duke
parents:
diff changeset
3642
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 void GraphBuilder::pop_scope_for_jsr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 _scope_data = scope_data()->parent();
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3646
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 Instruction* offset = args->at(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile));
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 push(op->type(), op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3661
a61af66fc99e Initial load
duke
parents:
diff changeset
3662
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 bool GraphBuilder::append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 Instruction* offset = args->at(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3677
a61af66fc99e Initial load
duke
parents:
diff changeset
3678
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 bool GraphBuilder::append_unsafe_get_raw(ciMethod* callee, BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 Instruction* op = append(new UnsafeGetRaw(t, args->at(1), false));
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 push(op->type(), op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3689
a61af66fc99e Initial load
duke
parents:
diff changeset
3690
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 bool GraphBuilder::append_unsafe_put_raw(ciMethod* callee, BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 Instruction* op = append(new UnsafePutRaw(t, args->at(1), args->at(2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3700
a61af66fc99e Initial load
duke
parents:
diff changeset
3701
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 bool GraphBuilder::append_unsafe_prefetch(ciMethod* callee, bool is_static, bool is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 int obj_arg_index = 1; // Assume non-static case
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 if (is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 obj_arg_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 Instruction* offset = args->at(obj_arg_index + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset))
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3721
a61af66fc99e Initial load
duke
parents:
diff changeset
3722
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3724 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 ValueType* result_type = as_ValueType(callee->return_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 assert(result_type->is_int(), "int result");
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3728
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 // Pop off some args to speically handle, then push back
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 Value newval = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 Value cmpval = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 Value offset = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 Value src = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 Value unsafe_obj = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3735
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 // Separately handle the unsafe arg. It is not needed for code
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 // generation, but must be null checked
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 null_check(unsafe_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3739
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 args->push(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 args->push(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 args->push(cmpval);
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 args->push(newval);
a61af66fc99e Initial load
duke
parents:
diff changeset
3748
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 // An unsafe CAS can alias with other field accesses, but we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 // know which ones so mark the state as no preserved. This will
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 // cause CSE to invalidate memory across it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 bool preserves_state = false;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3753 Intrinsic* result = new Intrinsic(result_type, callee->intrinsic_id(), args, false, state_before, preserves_state);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 append_split(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 push(result_type, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3758
a61af66fc99e Initial load
duke
parents:
diff changeset
3759
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 const char sync_char = callee->is_synchronized() ? 's' : ' ';
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 const char exception_char = callee->has_exception_handlers() ? '!' : ' ';
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 const char monitors_char = callee->has_monitor_bytecodes() ? 'm' : ' ';
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 tty->print(" %c%c%c ", sync_char, exception_char, monitors_char);
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 for (int i = 0; i < scope()->level(); i++) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 if (res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 tty->print("- ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 tty->print("@ %d ", bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 callee->print_short_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 tty->print(" (%d bytes)", callee->code_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 if (_inline_bailout_msg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 tty->print(" %s", _inline_bailout_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3779
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 if (res && CIPrintMethodCodes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 callee->print_codes();
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3784
a61af66fc99e Initial load
duke
parents:
diff changeset
3785
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 void GraphBuilder::print_stats() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 vmap()->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3790
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 append(new ProfileCall(method(), bci(), recv, known_holder));
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3794
1825
80c9354976b0 6988346: 6986046 breaks tiered
iveresov
parents: 1819
diff changeset
3795 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) {
80c9354976b0 6988346: 6986046 breaks tiered
iveresov
parents: 1819
diff changeset
3796 append(new ProfileInvoke(callee, state));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 }