annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 3249:e1162778c1c8

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