annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 1721:413ad0331a0c

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