annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 4710:41406797186b

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