annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 13212:eb03a7335eb0

Use fixed instead of virtual register for target in far foreign call, since the register allocator does not support virtual registers to be used at call sites.
author Christian Wimmer <christian.wimmer@oracle.com>
date Mon, 02 Dec 2013 14:20:32 -0800
parents 0097301f34fa
children d8041d695d19
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
2 * Copyright (c) 1999, 2013, 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"
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
34 #include "ci/ciMemberName.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 {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
890 assert(obj->is_instance(), "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);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
917 store_local(state(), x, index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
921 void GraphBuilder::store_local(ValueStack* state, Value x, int index) {
0
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) {
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
950 // In case of in block code motion in range check elimination
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
951 ValueStack* state_before = copy_state_indexed_access();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
952 compilation()->set_has_access_indexed(true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
953 Value index = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
954 Value array = apop();
a61af66fc99e Initial load
duke
parents:
diff changeset
955 Value length = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if (CSEArrayLength ||
a61af66fc99e Initial load
duke
parents:
diff changeset
957 (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
958 (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
959 length = append(new ArrayLength(array, state_before));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
960 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
961 push(as_ValueType(type), append(new LoadIndexed(array, index, length, type, state_before)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
962 }
a61af66fc99e Initial load
duke
parents:
diff changeset
963
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 void GraphBuilder::store_indexed(BasicType type) {
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
966 // In case of in block code motion in range check elimination
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
967 ValueStack* state_before = copy_state_indexed_access();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
968 compilation()->set_has_access_indexed(true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
969 Value value = pop(as_ValueType(type));
a61af66fc99e Initial load
duke
parents:
diff changeset
970 Value index = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
971 Value array = apop();
a61af66fc99e Initial load
duke
parents:
diff changeset
972 Value length = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
973 if (CSEArrayLength ||
a61af66fc99e Initial load
duke
parents:
diff changeset
974 (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
975 (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
976 length = append(new ArrayLength(array, state_before));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
978 StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
979 append(result);
459
3a86a8dcf27c 6756768: C1 generates invalid code
never
parents: 0
diff changeset
980 _memory->store_value(value);
1791
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 (type == T_OBJECT && is_profiling()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
983 // 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
984 compilation()->set_would_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
985
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
986 if (profile_checkcasts()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
987 result->set_profiled_method(method());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
988 result->set_profiled_bci(bci());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
989 result->set_should_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
990 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
991 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 void GraphBuilder::stack_op(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 case Bytecodes::_pop:
a61af66fc99e Initial load
duke
parents:
diff changeset
998 { state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 case Bytecodes::_pop2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 { state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 case Bytecodes::_dup:
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 { Value w = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 state()->raw_push(w);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 state()->raw_push(w);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 case Bytecodes::_dup_x1:
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 case Bytecodes::_dup_x2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 Value w3 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 state()->raw_push(w3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 case Bytecodes::_dup2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 case Bytecodes::_dup2_x1:
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 Value w3 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 state()->raw_push(w3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 case Bytecodes::_dup2_x2:
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 Value w3 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 Value w4 = state()->raw_pop();
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 state()->raw_push(w4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 state()->raw_push(w3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 case Bytecodes::_swap:
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 { Value w1 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 Value w2 = state()->raw_pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 state()->raw_push(w1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 state()->raw_push(w2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1077 void GraphBuilder::arithmetic_op(ValueType* type, Bytecodes::Code code, ValueStack* state_before) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // NOTE: strictfp can be queried from current method since we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // inline methods with differing strictfp bits
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1082 Value res = new ArithmeticOp(code, x, y, method()->is_strict(), state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // Note: currently single-precision floating-point rounding on Intel is handled at the LIRGenerator level
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 res = append(res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 res = round_fp(res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 push(type, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 void GraphBuilder::negate_op(ValueType* type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 push(type, append(new NegateOp(pop(type))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1095
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 void GraphBuilder::shift_op(ValueType* type, Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 Value s = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 // try to simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // Note: This code should go into the canonicalizer as soon as it can
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // can handle canonicalized forms that contain more than one node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 if (CanonicalizeNodes && code == Bytecodes::_iushr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // pattern: x >>> s
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 IntConstant* s1 = s->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 if (s1 != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // pattern: x >>> s1, with s1 constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 ShiftOp* l = x->as_ShiftOp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 if (l != NULL && l->op() == Bytecodes::_ishl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // pattern: (a << b) >>> s1
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 IntConstant* s0 = l->y()->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 if (s0 != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // pattern: (a << s0) >>> s1
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 const int s0c = s0->value() & 0x1F; // only the low 5 bits are significant for shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 const int s1c = s1->value() & 0x1F; // only the low 5 bits are significant for shifts
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 if (s0c == s1c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 if (s0c == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // pattern: (a << 0) >>> 0 => simplify to: a
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 ipush(l->x());
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // pattern: (a << s0c) >>> s0c => simplify to: a & m, with m constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 assert(0 < s0c && s0c < BitsPerInt, "adjust code below to handle corner cases");
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 const int m = (1 << (BitsPerInt - s0c)) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 Value s = append(new Constant(new IntConstant(m)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 ipush(append(new LogicOp(Bytecodes::_iand, l->x(), s)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // could not simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 push(type, append(new ShiftOp(code, x, s)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 void GraphBuilder::logic_op(ValueType* type, Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 push(type, append(new LogicOp(code, x, y)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 void GraphBuilder::compare_op(ValueType* type, Bytecodes::Code code) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1146 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 ipush(append(new CompareOp(code, x, y, state_before)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1151
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 void GraphBuilder::convert(Bytecodes::Code op, BasicType from, BasicType to) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 push(as_ValueType(to), append(new Convert(op, pop(as_ValueType(from)), as_ValueType(to))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 void GraphBuilder::increment() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 int index = stream()->get_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 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
1161 load_local(intType, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 ipush(append(new Constant(new IntConstant(delta))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 arithmetic_op(intType, Bytecodes::_iadd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 store_local(intType, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 void GraphBuilder::_goto(int from_bci, int to_bci) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1169 Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1170 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1171 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1172 x->set_profiled_bci(bci());
3997
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3901
diff changeset
1173 if (profile_branches()) {
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3901
diff changeset
1174 x->set_profiled_method(method());
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3901
diff changeset
1175 x->set_should_profile(true);
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3901
diff changeset
1176 }
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1177 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1178 append(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1180
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 BlockBegin* tsux = block_at(stream()->get_dest());
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 BlockBegin* fsux = block_at(stream()->next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1186 // In case of loop invariant code motion or predicate insertion
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1187 // before the body of a loop the state is needed
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1188 Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic()) ? state_before : NULL, is_bb));
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1189
4943
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1190 assert(i->as_Goto() == NULL ||
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1191 (i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1192 (i->as_Goto()->sux_at(0) == fsux && i->as_Goto()->is_safepoint() == fsux->bci() < stream()->cur_bci()),
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1193 "safepoint state of Goto returned by canonicalizer incorrect");
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1194
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1195 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1196 If* if_node = i->as_If();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1197 if (if_node != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1198 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1199 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1200 // At level 2 we need the proper bci to count backedges
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1201 if_node->set_profiled_bci(bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1202 if (profile_branches()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1203 // Successors can be rotated by the canonicalizer, check for this case.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1204 if_node->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1205 if_node->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1206 if (if_node->tsux() == fsux) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1207 if_node->set_swapped(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1208 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1209 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1210 return;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1211 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1212
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1213 // Check if this If was reduced to Goto.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1214 Goto *goto_node = i->as_Goto();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1215 if (goto_node != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1216 compilation()->set_would_profile(true);
3997
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3901
diff changeset
1217 goto_node->set_profiled_bci(bci());
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1218 if (profile_branches()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1219 goto_node->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1220 goto_node->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1221 // Find out which successor is used.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1222 if (goto_node->default_sux() == tsux) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1223 goto_node->set_direction(Goto::taken);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1224 } else if (goto_node->default_sux() == fsux) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1225 goto_node->set_direction(Goto::not_taken);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1226 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1227 ShouldNotReachHere();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1228 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1229 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1230 return;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1231 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 void GraphBuilder::if_zero(ValueType* type, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 Value y = append(new Constant(intZero));
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1238 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 Value x = ipop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 if_node(x, cond, y, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 void GraphBuilder::if_null(ValueType* type, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 Value y = append(new Constant(objectNull));
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1246 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 Value x = apop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 if_node(x, cond, y, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 void GraphBuilder::if_same(ValueType* type, If::Condition cond) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1253 ValueStack* state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 Value y = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 Value x = pop(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 if_node(x, cond, y, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 void GraphBuilder::jsr(int dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // We only handle well-formed jsrs (those which are "block-structured").
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 // If the bytecodes are strange (jumping out of a jsr block) then we
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // might end up trying to re-parse a block containing a jsr which
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // has already been activated. Watch for this case and bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 for (ScopeData* cur_scope_data = scope_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 cur_scope_data = cur_scope_data->parent()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 if (cur_scope_data->jsr_entry_bci() == dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 BAILOUT("too-complicated jsr/ret structure");
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 push(addressType, append(new Constant(new AddressConstant(next_bci()))));
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 if (!try_inline_jsr(dest)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 return; // bailed out while parsing and inlining subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1278
a61af66fc99e Initial load
duke
parents:
diff changeset
1279
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 void GraphBuilder::ret(int local_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 if (!parsing_jsr()) BAILOUT("ret encountered while not parsing subroutine");
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 if (local_index != scope_data()->jsr_return_address_local()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 BAILOUT("can not handle complicated jsr/ret constructs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1286
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // Rets simply become (NON-SAFEPOINT) gotos to the jsr continuation
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 append(new Goto(scope_data()->jsr_continuation(), false));
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1290
a61af66fc99e Initial load
duke
parents:
diff changeset
1291
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 void GraphBuilder::table_switch() {
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1293 Bytecode_tableswitch sw(stream());
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1294 const int l = sw.length();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 if (CanonicalizeNodes && l == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // total of 2 successors => use If instead of switch
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // Note: This code should go into the canonicalizer as soon as it can
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // can handle canonicalized forms that contain more than one node.
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1299 Value key = append(new Constant(new IntConstant(sw.low_key())));
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1300 BlockBegin* tsux = block_at(bci() + sw.dest_offset_at(0));
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1301 BlockBegin* fsux = block_at(bci() + sw.default_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1303 // In case of loop invariant code motion or predicate insertion
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1304 // before the body of a loop the state is needed
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1305 ValueStack* state_before = copy_state_if_bb(is_bb);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // collect successors
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 BlockList* sux = new BlockList(l + 1, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 bool has_bb = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 for (i = 0; i < l; i++) {
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1313 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
1314 if (sw.dest_offset_at(i) < 0) has_bb = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // add default successor
5925
4fabc16dc5bf 6910464: Lookupswitch and Tableswitch default branches not recognized as safepoints
roland
parents: 4943
diff changeset
1317 if (sw.default_offset() < 0) has_bb = true;
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1318 sux->at_put(i, block_at(bci() + sw.default_offset()));
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1319 // In case of loop invariant code motion or predicate insertion
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1320 // before the body of a loop the state is needed
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1321 ValueStack* state_before = copy_state_if_bb(has_bb);
4943
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1322 Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1323 #ifdef ASSERT
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1324 if (res->as_Goto()) {
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1325 for (i = 0; i < l; i++) {
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1326 if (sux->at(i) == res->as_Goto()->sux_at(0)) {
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1327 assert(res->as_Goto()->is_safepoint() == sw.dest_offset_at(i) < 0, "safepoint state of Goto returned by canonicalizer incorrect");
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1328 }
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1329 }
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1330 }
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1331 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1334
a61af66fc99e Initial load
duke
parents:
diff changeset
1335
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 void GraphBuilder::lookup_switch() {
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1337 Bytecode_lookupswitch sw(stream());
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1338 const int l = sw.number_of_pairs();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 if (CanonicalizeNodes && l == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // total of 2 successors => use If instead of switch
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // Note: This code should go into the canonicalizer as soon as it can
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // can handle canonicalized forms that contain more than one node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // simplify to If
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1344 LookupswitchPair pair = sw.pair_at(0);
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1345 Value key = append(new Constant(new IntConstant(pair.match())));
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1346 BlockBegin* tsux = block_at(bci() + pair.offset());
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1347 BlockBegin* fsux = block_at(bci() + sw.default_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1349 // In case of loop invariant code motion or predicate insertion
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1350 // before the body of a loop the state is needed
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1351 ValueStack* state_before = copy_state_if_bb(is_bb);;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // collect successors & keys
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 BlockList* sux = new BlockList(l + 1, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 intArray* keys = new intArray(l, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 bool has_bb = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 for (i = 0; i < l; i++) {
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1360 LookupswitchPair pair = sw.pair_at(i);
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1361 if (pair.offset() < 0) has_bb = true;
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1362 sux->at_put(i, block_at(bci() + pair.offset()));
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1363 keys->at_put(i, pair.match());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // add default successor
5925
4fabc16dc5bf 6910464: Lookupswitch and Tableswitch default branches not recognized as safepoints
roland
parents: 4943
diff changeset
1366 if (sw.default_offset() < 0) has_bb = true;
2142
8012aa3ccede 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 2007
diff changeset
1367 sux->at_put(i, block_at(bci() + sw.default_offset()));
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1368 // In case of loop invariant code motion or predicate insertion
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1369 // before the body of a loop the state is needed
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 7991
diff changeset
1370 ValueStack* state_before = copy_state_if_bb(has_bb);
4943
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1371 Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1372 #ifdef ASSERT
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1373 if (res->as_Goto()) {
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1374 for (i = 0; i < l; i++) {
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1375 if (sux->at(i) == res->as_Goto()->sux_at(0)) {
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1376 assert(res->as_Goto()->is_safepoint() == sw.pair_at(i).offset() < 0, "safepoint state of Goto returned by canonicalizer incorrect");
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1377 }
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1378 }
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1379 }
80107dc493db 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
roland
parents: 4871
diff changeset
1380 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 void GraphBuilder::call_register_finalizer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // If the receiver requires finalization then emit code to perform
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // the registration on return.
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // Gather some type information about the receiver
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1389 Value receiver = state()->local_at(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 assert(receiver != NULL, "must have a receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 ciType* declared_type = receiver->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 ciType* exact_type = receiver->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 if (exact_type == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 receiver->as_Local() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 receiver->as_Local()->java_index() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 ciInstanceKlass* ik = compilation()->method()->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 if (ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 exact_type = ik;
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 } else if (UseCHA && !(ik->has_subklass() || ik->is_interface())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // test class is leaf class
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 compilation()->dependency_recorder()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 exact_type = ik;
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 declared_type = ik;
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1407
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // see if we know statically that registration isn't required
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 bool needs_check = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 if (exact_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 needs_check = exact_type->as_instance_klass()->has_finalizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 } else if (declared_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 ciInstanceKlass* ik = declared_type->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 if (!Dependencies::has_finalizable_subclass(ik)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 compilation()->dependency_recorder()->assert_has_no_finalizable_subclasses(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 needs_check = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1419
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 if (needs_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // Perform the registration of finalizable objects.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1422 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 load_local(objectType, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 append_split(new Intrinsic(voidType, vmIntrinsics::_Object_init,
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 state()->pop_arguments(1),
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1426 true, state_before, true));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1429
a61af66fc99e Initial load
duke
parents:
diff changeset
1430
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 void GraphBuilder::method_return(Value x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 if (RegisterFinalizersAtInit &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 method()->intrinsic_id() == vmIntrinsics::_Object_init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 call_register_finalizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1436
4966
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1437 bool need_mem_bar = false;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1438 if (method()->name() == ciSymbol::object_initializer_name() &&
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1439 scope()->wrote_final()) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1440 need_mem_bar = true;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1441 }
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1442
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 // Check to see whether we are inlining. If so, Return
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // instructions become Gotos to the continuation point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 if (continuation() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
1447
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
1448 if (compilation()->env()->dtrace_method_probes()) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
1449 // Report exit from inline methods
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
1450 Values* args = new Values(1);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
1451 args->push(append(new Constant(new MethodConstant(method()))));
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
1452 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
1453 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
1454
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 // If the inlined method is synchronized, the monitor must be
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // released before we jump to the continuation block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 if (method()->is_synchronized()) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1458 assert(state()->locks_size() == 1, "receiver must be locked here");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1459 monitorexit(state()->lock_at(0), SynchronizationEntryBCI);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1461
4966
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1462 if (need_mem_bar) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1463 append(new MemBar(lir_membar_storestore));
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1464 }
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1465
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1466 // State at end of inlined method is the state of the caller
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1467 // without the method parameters on stack, including the
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1468 // return value, if any, of the inlined method on operand stack.
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1469 int invoke_bci = state()->caller_state()->bci();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1470 set_state(state()->caller_state()->copy_for_parsing());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 if (x != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 state()->push(x->type(), x);
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1473 if (profile_return() && x->type()->is_object_kind()) {
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1474 ciMethod* caller = state()->scope()->method();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1475 ciMethodData* md = caller->method_data_or_null();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1476 ciProfileData* data = md->bci_to_data(invoke_bci);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1477 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1478 bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1479 // May not be true in case of an inlined call through a method handle intrinsic.
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1480 if (has_return) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1481 profile_return_type(x, method(), caller, invoke_bci);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1482 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1483 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
1484 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 Goto* goto_callee = new Goto(continuation(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // See whether this is the first return; if so, store off some
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // of the state for later examination
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 if (num_returns() == 0) {
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1491 set_inline_cleanup_info();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1493
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 // The current bci() is in the wrong scope, so use the bci() of
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 // the continuation point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 append_with_bci(goto_callee, scope_data()->continuation()->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 incr_num_returns();
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1500
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 state()->truncate_stack(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 if (method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // perform the unlocking before exiting the method
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 Value receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 if (!method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 receiver = _initial_state->local_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 receiver = append(new Constant(new ClassConstant(method()->holder())));
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 append_split(new MonitorExit(receiver, state()->unlock()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1512
4966
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1513 if (need_mem_bar) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1514 append(new MemBar(lir_membar_storestore));
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1515 }
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1516
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 append(new Return(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
a61af66fc99e Initial load
duke
parents:
diff changeset
1520
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 void GraphBuilder::access_field(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 ciField* field = stream()->get_field(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 ciInstanceKlass* holder = field->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 BasicType field_type = field->type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 ValueType* type = as_ValueType(field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // 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
1528 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
1529 !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
1530 PatchALot;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1531
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1532 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
1533 if (!holder->is_initialized() || needs_patching) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 // save state before instruction for debug info when
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // deoptimization happens during patching
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1536 state_before = copy_state_before();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 Value obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1541 if (state_before != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // build a patching constant
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2352
diff changeset
1543 obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 } else {
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2352
diff changeset
1545 obj = new Constant(new InstanceConstant(holder->java_mirror()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
4966
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1549 if (field->is_final() && (code == Bytecodes::_putfield)) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1550 scope()->set_wrote_final();
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4943
diff changeset
1551 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1552
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
1553 const int offset = !needs_patching ? field->offset() : -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 case Bytecodes::_getstatic: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // check for compile-time constants, i.e., initialized static final fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 Instruction* constant = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 if (field->is_constant() && !PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 ciConstant field_val = field->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 BasicType field_type = field_val.basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 switch (field_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 case T_OBJECT:
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
1564 if (field_val.as_object()->should_be_constant()) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1565 constant = new Constant(as_ValueType(field_val));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1568
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 constant = new Constant(as_ValueType(field_val));
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 if (constant != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 push(type, append(constant));
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 } else {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1576 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1577 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1578 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 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
1580 state_before, needs_patching)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 case Bytecodes::_putstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 { Value val = pop(type);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1586 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1587 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1588 }
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
1589 append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 break;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1592 case Bytecodes::_getfield: {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1593 // Check for compile-time constants, i.e., trusted final non-static fields.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1594 Instruction* constant = NULL;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1595 obj = apop();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1596 ObjectType* obj_type = obj->type()->as_ObjectType();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1597 if (obj_type->is_constant() && !PatchALot) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1598 ciObject* const_oop = obj_type->constant_value();
12165
59982ff9e0ec 8022283: Assertion failed: assert(is_loaded() && field->holder()->is_loaded() && klass()->is_subclass_of (field->holder())) failed: invalid access
rbackman
parents: 12160
diff changeset
1599 if (!const_oop->is_null_object() && const_oop->is_loaded()) {
6267
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1600 if (field->is_constant()) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1601 ciConstant field_val = field->constant_value_of(const_oop);
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1602 BasicType field_type = field_val.basic_type();
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1603 switch (field_type) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1604 case T_ARRAY:
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1605 case T_OBJECT:
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1606 if (field_val.as_object()->should_be_constant()) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1607 constant = new Constant(as_ValueType(field_val));
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1608 }
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1609 break;
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1610 default:
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1611 constant = new Constant(as_ValueType(field_val));
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1612 }
6267
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1613 } else {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1614 // For CallSite objects treat the target field as a compile time constant.
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1615 if (const_oop->is_call_site()) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1616 ciCallSite* call_site = const_oop->as_call_site();
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1617 if (field->is_call_site_target()) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1618 ciMethodHandle* target = call_site->get_target();
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1619 if (target != NULL) { // just in case
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1620 ciConstant field_val(T_OBJECT, target);
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1621 constant = new Constant(as_ValueType(field_val));
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1622 // Add a dependence for invalidation of the optimization.
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1623 if (!call_site->is_constant_call_site()) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1624 dependency_recorder()->assert_call_site_target_value(call_site, target);
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
1625 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1626 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1627 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1628 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1629 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1630 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1631 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1632 if (constant != NULL) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1633 push(type, append(constant));
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1634 } else {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1635 if (state_before == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1636 state_before = copy_state_for_exception();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1637 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1638 LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching);
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
1639 Value replacement = !needs_patching ? _memory->load(load) : load;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 if (replacement != load) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1641 assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 push(type, replacement);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 push(type, append(load));
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 break;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1648 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1649 case Bytecodes::_putfield: {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1650 Value val = pop(type);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1651 obj = apop();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1652 if (state_before == NULL) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1653 state_before = copy_state_for_exception();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1654 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1655 StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1656 if (!needs_patching) store = _memory->store(store);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1657 if (store != NULL) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1658 append(store);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1659 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1660 break;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1661 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1662 default:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1667
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 Dependencies* GraphBuilder::dependency_recorder() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 assert(DeoptC1, "need debug information");
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 return compilation()->dependency_recorder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1674 // How many arguments do we want to profile?
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1675 Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1676 int n = 0;
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1677 bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1678 start = has_receiver ? 1 : 0;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1679 if (profile_arguments()) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1680 ciProfileData* data = method()->method_data()->bci_to_data(bci());
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1681 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1682 n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1683 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1684 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1685 // If we are inlining then we need to collect arguments to profile parameters for the target
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1686 if (profile_parameters() && target != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1687 if (target->method_data() != NULL && target->method_data()->parameters_type_data() != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1688 // The receiver is profiled on method entry so it's included in
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1689 // the number of parameters but here we're only interested in
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1690 // actual arguments.
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1691 n = MAX2(n, target->method_data()->parameters_type_data()->number_of_parameters() - start);
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1692 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1693 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1694 if (n > 0) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1695 return new Values(n);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1696 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1697 return NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1698 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1699
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1700 // Collect arguments that we want to profile in a list
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1701 Values* GraphBuilder::collect_args_for_profiling(Values* args, ciMethod* target, bool may_have_receiver) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1702 int start = 0;
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
1703 Values* obj_args = args_list_for_profiling(target, start, may_have_receiver);
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1704 if (obj_args == NULL) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1705 return NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1706 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1707 int s = obj_args->size();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1708 for (int i = start, j = 0; j < s; i++) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1709 if (args->at(i)->type()->is_object_kind()) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1710 obj_args->push(args->at(i));
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1711 j++;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1712 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1713 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1714 assert(s == obj_args->length(), "missed on arg?");
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1715 return obj_args;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1716 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
1717
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1718
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 void GraphBuilder::invoke(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 bool will_link;
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6616
diff changeset
1721 ciSignature* declared_signature = NULL;
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6616
diff changeset
1722 ciMethod* target = stream()->get_method(will_link, &declared_signature);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1723 ciKlass* holder = stream()->get_declared_method_holder();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1724 const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6616
diff changeset
1725 assert(declared_signature != NULL, "cannot be null");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1726
12160
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1727 if (!C1PatchInvokeDynamic && Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1728 BAILOUT("unlinked call site (C1PatchInvokeDynamic is off)");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1729 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1730
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 // we have to make sure the argument size (incl. the receiver)
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // is correct for compilation (the call would fail later during
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // linkage anyway) - was bug (gri 7/28/99)
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1734 {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1735 // Use raw to get rewritten bytecode.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1736 const bool is_invokestatic = bc_raw == Bytecodes::_invokestatic;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1737 const bool allow_static =
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1738 is_invokestatic ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1739 bc_raw == Bytecodes::_invokehandle ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1740 bc_raw == Bytecodes::_invokedynamic;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1741 if (target->is_loaded()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1742 if (( target->is_static() && !allow_static) ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1743 (!target->is_static() && is_invokestatic)) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1744 BAILOUT("will cause link error");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1745 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1746 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1747 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 ciInstanceKlass* klass = target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // check if CHA possible: if so, change the code to invoke_special
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 ciInstanceKlass* calling_klass = method()->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 ciInstanceKlass* actual_recv = callee_holder;
a61af66fc99e Initial load
duke
parents:
diff changeset
1754
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1755 CompileLog* log = compilation()->log();
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1756 if (log != NULL)
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1757 log->elem("call method='%d' instr='%s'",
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1758 log->identify(target),
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1759 Bytecodes::name(code));
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1760
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1761 // Some methods are obviously bindable without any type checks so
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1762 // convert them directly to an invokespecial or invokestatic.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1763 if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1764 switch (bc_raw) {
6616
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1765 case Bytecodes::_invokevirtual:
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1766 code = Bytecodes::_invokespecial;
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1767 break;
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1768 case Bytecodes::_invokehandle:
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1769 code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1770 break;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1771 }
12160
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1772 } else {
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1773 if (bc_raw == Bytecodes::_invokehandle) {
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1774 assert(!will_link, "should come here only for unlinked call");
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1775 code = Bytecodes::_invokespecial;
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1776 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1779 // Push appendix argument (MethodType, CallSite, etc.), if one.
12160
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1780 bool patch_for_appendix = false;
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1781 int patching_appendix_arg = 0;
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1782 if (C1PatchInvokeDynamic &&
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1783 (Bytecodes::has_optional_appendix(bc_raw) && (!will_link || PatchALot))) {
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1784 Value arg = append(new Constant(new ObjectConstant(compilation()->env()->unloaded_ciinstance()), copy_state_before()));
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1785 apush(arg);
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1786 patch_for_appendix = true;
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1787 patching_appendix_arg = (will_link && stream()->has_appendix()) ? 0 : 1;
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1788 } else if (stream()->has_appendix()) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1789 ciObject* appendix = stream()->get_appendix();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1790 Value arg = append(new Constant(new ObjectConstant(appendix)));
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1791 apush(arg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1792 }
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1793
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // NEEDS_CLEANUP
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1795 // I've added the target->is_loaded() test below but I don't really understand
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // how klass->is_loaded() can be true and yet target->is_loaded() is false.
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 // this happened while running the JCK invokevirtual tests under doit. TKR
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 ciMethod* cha_monomorphic_target = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 ciMethod* exact_target = NULL;
4871
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1800 Value better_receiver = NULL;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1801 if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1802 !(// %%% FIXME: Are both of these relevant?
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1803 target->is_method_handle_intrinsic() ||
12160
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1804 target->is_compiled_lambda_form()) &&
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1805 !patch_for_appendix) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 Value receiver = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 ciInstanceKlass* receiver_klass = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 bool type_is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // try to find a precise receiver type
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 if (will_link && !target->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 int index = state()->stack_size() - (target->arg_size_no_receiver() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 receiver = state()->stack_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 ciType* type = receiver->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 if (type != NULL && type->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 receiver_klass = (ciInstanceKlass*) type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 if (type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 type = receiver->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 if (type != NULL && type->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 receiver_klass = (ciInstanceKlass*) type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (receiver_klass->is_leaf_type() && !receiver_klass->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 // Insert a dependency on this type since
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 // find_monomorphic_target may assume it's already done.
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 dependency_recorder()->assert_leaf_type(receiver_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 if (receiver_klass != NULL && type_is_exact &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 receiver_klass->is_loaded() && code != Bytecodes::_invokespecial) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // If we have the exact receiver type we can bind directly to
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 // the method to call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 exact_target = target->resolve_invoke(calling_klass, receiver_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 if (exact_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 target = exact_target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 code = Bytecodes::_invokespecial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 if (receiver_klass != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 receiver_klass->is_subtype_of(actual_recv) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 actual_recv->is_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 actual_recv = receiver_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1848
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 (code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // Use CHA on the receiver to select a more precise method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 } else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 // if there is only one implementor of this interface then we
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 // may be able bind this invoke directly to the implementing
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // klass but we need both a dependence on the single interface
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 // and on the method we bind to. Additionally since all we know
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 // about the receiver type is the it's supposed to implement the
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 // interface we have to insert a check that it's the class we
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // expect. Interface types are not checked by the verifier so
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 // they are roughly equivalent to Object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 ciInstanceKlass* singleton = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 if (target->holder()->nof_implementors() == 1) {
5998
49036505ab5f 7154670: The instanceKlass _implementors[] and _nof_implementors are not needed for non-interface klass.
jiangli
parents: 5926
diff changeset
1864 singleton = target->holder()->implementor();
49036505ab5f 7154670: The instanceKlass _implementors[] and _nof_implementors are not needed for non-interface klass.
jiangli
parents: 5926
diff changeset
1865 assert(singleton != NULL && singleton != target->holder(),
49036505ab5f 7154670: The instanceKlass _implementors[] and _nof_implementors are not needed for non-interface klass.
jiangli
parents: 5926
diff changeset
1866 "just checking");
4871
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1867
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1868 assert(holder->is_interface(), "invokeinterface to non interface?");
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1869 ciInstanceKlass* decl_interface = (ciInstanceKlass*)holder;
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1870 // the number of implementors for decl_interface is less or
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1871 // equal to the number of implementors for target->holder() so
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1872 // if number of implementors of target->holder() == 1 then
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1873 // number of implementors for decl_interface is 0 or 1. If
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1874 // it's 0 then no class implements decl_interface and there's
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1875 // no point in inlining.
13021
4d3575d37a07 8026735: Stream tests throw java.lang.IncompatibleClassChangeError
iveresov
parents: 12975
diff changeset
1876 if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_default_methods()) {
4871
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1877 singleton = NULL;
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1878 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 if (singleton) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 // If CHA is able to bind this invoke then update the class
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 // to match that class, otherwise klass will refer to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 // interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 klass = cha_monomorphic_target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 actual_recv = target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1888
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // insert a check it's really the expected class.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
1890 CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 c->set_incompatible_class_change_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 c->set_direct_compare(klass->is_final());
4871
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1893 // pass the result of the checkcast so that the compiler has
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1894 // more accurate type info in the inlinee
f067b4e0e04b 7090976: Eclipse/CDT causes a JVM crash while indexing C++ code
roland
parents: 4870
diff changeset
1895 better_receiver = append_split(c);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1900
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 if (cha_monomorphic_target->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 // Do not optimize for abstract methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 cha_monomorphic_target = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1907
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 if (!(target->is_final_method())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 // If we inlined because CHA revealed only a single target method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 // then we are dependent on that target method not getting overridden
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 // by dynamic class loading. Be sure to test the "static" receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 // dest_method here, as opposed to the actual receiver, which may
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 // falsely lead us to believe that the receiver is final or private.
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 code = Bytecodes::_invokespecial;
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 }
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
1919
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 // check if we could do inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 if (!PatchALot && Inline && klass->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
12160
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1923 && target->is_loaded()
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1924 && !patch_for_appendix) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 // callee is known => check if we have static binding
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 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
1927 if (code == Bytecodes::_invokestatic ||
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1928 code == Bytecodes::_invokespecial ||
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1929 code == Bytecodes::_invokevirtual && target->is_final_method() ||
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1930 code == Bytecodes::_invokedynamic) {
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1931 ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
6892
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
1932 // static binding => check if callee is ok
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
1933 bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
1934
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 clear_inline_bailout();
6892
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
1937
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
1938 if (success) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // Register dependence if JVMTI has either breakpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // setting or hotswapping of methods capabilities since they may
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 // 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
1942 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 dependency_recorder()->assert_evol_method(inline_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1947 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1948 print_inlining(target, "no static binding", /*success*/ false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1950 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1951 print_inlining(target, "not inlineable", /*success*/ false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
1953
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // If we attempted an inline which did not succeed because of a
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 // bailout during construction of the callee graph, the entire
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // compilation has to be aborted. This is fairly rare and currently
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // seems to only occur for jasm-generated classes which contain
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // jsr/ret pairs which are not associated with finally clauses and
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 // do not have exception handlers in the containing method, and are
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 // therefore not caught early enough to abort the inlining without
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // corrupting the graph. (We currently bail out with a non-empty
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // stack at a ret in these situations.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // inlining not successful => standard invoke
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1966 bool is_loaded = target->is_loaded();
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6616
diff changeset
1967 ValueType* result_type = as_ValueType(declared_signature->return_type());
6616
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1968 ValueStack* state_before = copy_state_exhandling();
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1969
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1970 // The bytecode (code) might change in this method so we are checking this very late.
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1971 const bool has_receiver =
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1972 code == Bytecodes::_invokespecial ||
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1973 code == Bytecodes::_invokevirtual ||
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
1974 code == Bytecodes::_invokeinterface;
12160
f98f5d48f511 7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents: 11080
diff changeset
1975 Values* args = state()->pop_arguments(target->arg_size_no_receiver() + patching_appendix_arg);
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
1976 Value recv = has_receiver ? apop() : NULL;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
1977 int vtable_index = Method::invalid_vtable_index;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1978
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 // Currently only supported on Sparc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 // The UseInlineCaches only controls dispatch to invokevirtuals for
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 // loaded classes which we weren't able to statically bind.
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 && !target->can_be_statically_bound()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 // Find a vtable index if one is available
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 vtable_index = target->resolve_vtable_index(calling_klass, callee_holder);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1989
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 if (recv != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 (code == Bytecodes::_invokespecial ||
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
1992 !is_loaded || target->is_final())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // invokespecial always needs a NULL check. invokevirtual where
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // the target is final or where it's not known that whether the
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 // target is final requires a NULL check. Otherwise normal
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // invokevirtual will perform the null check during the lookup
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // logic or the unverified entry point. Profiling of calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 // requires that the null check is performed in all cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 null_check(recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2001
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2002 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2003 if (recv != NULL && profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2004 null_check(recv);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 }
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2006 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2007 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2008
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2009 if (profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2010 assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2011 ciKlass* target_klass = NULL;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2012 if (cha_monomorphic_target != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2013 target_klass = cha_monomorphic_target->holder();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2014 } else if (exact_target != NULL) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2015 target_klass = exact_target->holder();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2016 }
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
2017 profile_call(target, recv, target_klass, collect_args_for_profiling(args, NULL, false), false);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2018 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1060
diff changeset
2021 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 // push result
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 append_split(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2024
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 if (result_type != voidType) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 push(result_type, round_fp(result));
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 push(result_type, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 }
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
2032 if (profile_return() && result_type->is_object_kind()) {
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
2033 profile_return_type(result, target);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
2034 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2036
a61af66fc99e Initial load
duke
parents:
diff changeset
2037
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 void GraphBuilder::new_instance(int klass_index) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2039 ValueStack* state_before = copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 ciKlass* klass = stream()->get_klass(will_link);
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 assert(klass->is_instance_klass(), "must be an instance klass");
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2043 NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 _memory->new_instance(new_instance);
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 apush(append_split(new_instance));
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 void GraphBuilder::new_type_array() {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2050 ValueStack* state_before = copy_state_exhandling();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2051 apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2053
a61af66fc99e Initial load
duke
parents:
diff changeset
2054
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 void GraphBuilder::new_object_array() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2058 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 NewArray* n = new NewObjectArray(klass, ipop(), state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 apush(append_split(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2062
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 bool GraphBuilder::direct_compare(ciKlass* k) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 if (k->is_loaded() && k->is_instance_klass() && !UseSlowPath) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 ciInstanceKlass* ik = k->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 if (ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 if (DeoptC1 && UseCHA && !(ik->has_subklass() || ik->is_interface())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // test class is leaf class
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 dependency_recorder()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2079
a61af66fc99e Initial load
duke
parents:
diff changeset
2080
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 void GraphBuilder::check_cast(int klass_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2084 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 CheckCast* c = new CheckCast(klass, apop(), state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 apush(append_split(c));
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 c->set_direct_compare(direct_compare(klass));
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2088
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2089 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2090 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2091 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2092
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2093 if (profile_checkcasts()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2094 c->set_profiled_method(method());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2095 c->set_profiled_bci(bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2096 c->set_should_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2097 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2100
a61af66fc99e Initial load
duke
parents:
diff changeset
2101
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 void GraphBuilder::instance_of(int klass_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2105 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 InstanceOf* i = new InstanceOf(klass, apop(), state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 ipush(append_split(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 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
2109
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2110 if (is_profiling()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2111 // 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
2112 compilation()->set_would_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2113
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2114 if (profile_checkcasts()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2115 i->set_profiled_method(method());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2116 i->set_profiled_bci(bci());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2117 i->set_should_profile(true);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2118 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2119 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2121
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 void GraphBuilder::monitorenter(Value x, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 // save state before locking in case of deoptimization after a NullPointerException
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2125 ValueStack* state_before = copy_state_for_exception_with_bci(bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2126 append_with_bci(new MonitorEnter(x, state()->lock(x), state_before), bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2129
a61af66fc99e Initial load
duke
parents:
diff changeset
2130
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 void GraphBuilder::monitorexit(Value x, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 append_with_bci(new MonitorExit(x, state()->unlock()), bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2135
a61af66fc99e Initial load
duke
parents:
diff changeset
2136
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 void GraphBuilder::new_multi_array(int dimensions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 bool will_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 ciKlass* klass = stream()->get_klass(will_link);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2140 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 Values* dims = new Values(dimensions, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // fill in all dimensions
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 int i = dimensions;
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 while (i-- > 0) dims->at_put(i, ipop());
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 // create array
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 NewArray* n = new NewMultiArray(klass, dims, state_before);
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 apush(append_split(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2150
a61af66fc99e Initial load
duke
parents:
diff changeset
2151
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 void GraphBuilder::throw_op(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // We require that the debug info for a Throw be the "state before"
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 // the Throw (i.e., exception oop is still on TOS)
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2155 ValueStack* state_before = copy_state_before_with_bci(bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 Throw* t = new Throw(apop(), state_before);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2157 // operand stack not needed after a throw
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2158 state()->truncate_stack(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 append_with_bci(t, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2161
a61af66fc99e Initial load
duke
parents:
diff changeset
2162
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 Value GraphBuilder::round_fp(Value fp_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 // no rounding needed if SSE2 is used
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 if (RoundFPResults && UseSSE < 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // Must currently insert rounding node for doubleword values that
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // are results of expressions (i.e., not loads from memory or
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 // constants)
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 if (fp_value->type()->tag() == doubleTag &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 fp_value->as_Constant() == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 fp_value->as_Local() == NULL && // method parameters need no rounding
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 fp_value->as_RoundFP() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 return append(new RoundFP(fp_value));
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 return fp_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2181 Canonicalizer canon(compilation(), instr, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 Instruction* i1 = canon.canonical();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2183 if (i1->is_linked() || !i1->can_be_linked()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // Canonicalizer returned an instruction which was already
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // appended so simply return it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 return i1;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2187 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2188
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2189 if (UseLocalValueNumbering) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // Lookup the instruction in the ValueMap and add it to the map if
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 // it's not found.
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 Instruction* i2 = vmap()->find_insert(i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 if (i2 != i1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 // found an entry in the value map, so just return it.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2195 assert(i2->is_linked(), "should already be linked");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 return i2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 }
459
3a86a8dcf27c 6756768: C1 generates invalid code
never
parents: 0
diff changeset
2198 ValueNumberingEffects vne(vmap());
3a86a8dcf27c 6756768: C1 generates invalid code
never
parents: 0
diff changeset
2199 i1->visit(&vne);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2201
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2202 // i1 was not eliminated => append it
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2203 assert(i1->next() == NULL, "shouldn't already be linked");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2204 _last = _last->set_next(i1, canon.bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2205
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2206 if (++_instruction_count >= InstructionCountCutoff && !bailed_out()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2207 // set the bailout state but complete normal processing. We
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2208 // might do a little more work before noticing the bailout so we
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2209 // want processing to continue normally until it's noticed.
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2210 bailout("Method and/or inlining is too large");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2211 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2212
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 #ifndef PRODUCT
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2214 if (PrintIRDuringConstruction) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2215 InstructionPrinter ip;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2216 ip.print_line(i1);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2217 if (Verbose) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2218 state()->print();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2219 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2220 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2221 #endif
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2222
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2223 // save state after modification of operand stack for StateSplit instructions
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2224 StateSplit* s = i1->as_StateSplit();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2225 if (s != NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2226 if (EliminateFieldAccess) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2227 Intrinsic* intrinsic = s->as_Intrinsic();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2228 if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2229 _memory->kill();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2232 s->set_state(state()->copy(ValueStack::StateAfter, canon.bci()));
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2233 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2234
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2235 // set up exception handlers for this instruction if necessary
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2236 if (i1->can_trap()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2237 i1->set_exception_handlers(handle_exception(i1));
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2238 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
2239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 return i1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2242
a61af66fc99e Initial load
duke
parents:
diff changeset
2243
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 Instruction* GraphBuilder::append(Instruction* instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 assert(instr->as_StateSplit() == NULL || instr->as_BlockEnd() != NULL, "wrong append used");
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 return append_with_bci(instr, bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2248
a61af66fc99e Initial load
duke
parents:
diff changeset
2249
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 Instruction* GraphBuilder::append_split(StateSplit* instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 return append_with_bci(instr, bci());
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 void GraphBuilder::null_check(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 if (value->as_NewArray() != NULL || value->as_NewInstance() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 Constant* con = value->as_Constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 if (con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 ObjectType* c = con->type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 if (c && c->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 ObjectConstant* oc = c->as_ObjectConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 if (!oc || !oc->value()->is_null_object()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2270 append(new NullCheck(value, copy_state_for_exception()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2272
a61af66fc99e Initial load
duke
parents:
diff changeset
2273
a61af66fc99e Initial load
duke
parents:
diff changeset
2274
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2275 XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2276 if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2277 assert(instruction->exception_state() == NULL
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2278 || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2279 || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()),
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2280 "exception_state should be of exception kind");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 return new XHandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 XHandlers* exception_handlers = new XHandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 ScopeData* cur_scope_data = scope_data();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2286 ValueStack* cur_state = instruction->state_before();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2287 ValueStack* prev_state = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 int scope_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2289
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2290 assert(cur_state != NULL, "state_before must be set");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 do {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2292 int cur_bci = cur_state->bci();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2293 assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci");
a61af66fc99e Initial load
duke
parents:
diff changeset
2295
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 // join with all potential exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 XHandlers* list = cur_scope_data->xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 const int n = list->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 for (int i = 0; i < n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 XHandler* h = list->handler_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 if (h->covers(cur_bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 // h is a potential exception handler => join it
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 compilation()->set_has_exception_handlers(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2304
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 BlockBegin* entry = h->entry_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 if (entry == block()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 // It's acceptable for an exception handler to cover itself
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 // but we don't handle that in the parser currently. It's
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 // very rare so we bailout instead of trying to handle it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 BAILOUT_("exception handler covers itself", exception_handlers);
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 assert(entry->bci() == h->handler_bci(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 assert(entry->bci() == -1 || entry == cur_scope_data->block_at(entry->bci()), "blocks must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
2314
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // previously this was a BAILOUT, but this is not necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 // now because asynchronous exceptions are not handled this way.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2317 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
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 // xhandler start with an empty expression stack
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2320 if (cur_state->stack_size() != 0) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2321 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2322 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2323 if (instruction->exception_state() == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2324 instruction->set_exception_state(cur_state);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2325 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2326
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 // Note: Usually this join must work. However, very
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // complicated jsr-ret structures where we don't ret from
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 // the subroutine can cause the objects on the monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 // stacks to not match because blocks can be parsed twice.
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 // The only test case we've seen so far which exhibits this
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 // problem is caught by the infinite recursion test in
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 // GraphBuilder::jsr() if the join doesn't work.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2334 if (!entry->try_merge(cur_state)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 BAILOUT_("error while joining with exception handler, prob. due to complicated jsr/rets", exception_handlers);
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2337
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 // add current state for correct handling of phi functions at begin of xhandler
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2339 int phi_operand = entry->add_exception_state(cur_state);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2340
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // add entry to the list of xhandlers of this block
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 _block->add_exception_handler(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
2343
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 // add back-edge from xhandler entry to this block
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 if (!entry->is_predecessor(_block)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 entry->add_predecessor(_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 // clone XHandler because phi_operand and scope_count can not be shared
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 XHandler* new_xhandler = new XHandler(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 new_xhandler->set_phi_operand(phi_operand);
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 new_xhandler->set_scope_count(scope_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 exception_handlers->append(new_xhandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2354
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 // fill in exception handler subgraph lazily
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 cur_scope_data->add_to_work_list(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
2358
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 // stop when reaching catchall
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 if (h->catch_type() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 return exception_handlers;
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2365
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2366 if (exception_handlers->length() == 0) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2367 // This scope and all callees do not handle exceptions, so the local
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2368 // variables of this scope are not needed. However, the scope itself is
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2369 // required for a correct exception stack trace -> clear out the locals.
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2370 if (_compilation->env()->jvmti_can_access_local_variables()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2371 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2372 } else {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2373 cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2374 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2375 if (prev_state != NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2376 prev_state->set_caller_state(cur_state);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2377 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2378 if (instruction->exception_state() == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2379 instruction->set_exception_state(cur_state);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2380 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2381 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2382
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 // Set up iteration for next time.
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 // If parsing a jsr, do not grab exception handlers from the
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 // parent scopes for this method (already got them, and they
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 // needed to be cloned)
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2387
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2388 while (cur_scope_data->parsing_jsr()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2389 cur_scope_data = cur_scope_data->parent();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2391
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2392 assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2393 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
2394
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2395 prev_state = cur_state;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2396 cur_state = cur_state->caller_state();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2397 cur_scope_data = cur_scope_data->parent();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2398 scope_count++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 } while (cur_scope_data != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2400
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 return exception_handlers;
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2403
a61af66fc99e Initial load
duke
parents:
diff changeset
2404
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 // Helper class for simplifying Phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 class PhiSimplifier : public BlockClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 bool _has_substitutions;
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 Value simplify(Value v);
a61af66fc99e Initial load
duke
parents:
diff changeset
2410
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 PhiSimplifier(BlockBegin* start) : _has_substitutions(false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 start->iterate_preorder(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 if (_has_substitutions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 SubstitutionResolver sr(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 void block_do(BlockBegin* b);
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 bool has_substitutions() const { return _has_substitutions; }
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2421
a61af66fc99e Initial load
duke
parents:
diff changeset
2422
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 Value PhiSimplifier::simplify(Value v) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 Phi* phi = v->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2425
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 if (phi == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 // no phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 return v;
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 } else if (v->has_subst()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 // already substituted; subst can be phi itself -> simplify
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 return simplify(v->subst());
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 } else if (phi->is_set(Phi::cannot_simplify)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 // already tried to simplify phi before
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 } else if (phi->is_set(Phi::visited)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 // break cycles in phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 } else if (phi->type()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 // illegal phi functions are ignored anyway
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2441
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 // mark phi function as processed to break cycles in phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 phi->set(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2445
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 // simplify x = [y, x] and x = [y, y] to y
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 Value subst = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 int opd_count = phi->operand_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 for (int i = 0; i < opd_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 Value opd = phi->operand_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 assert(opd != NULL, "Operand must exist!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2452
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 if (opd->type()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 // if one operand is illegal, the entire phi function is illegal
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 phi->make_illegal();
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 phi->clear(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2459
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 Value new_opd = simplify(opd);
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 assert(new_opd != NULL, "Simplified operand must exist!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 if (new_opd != phi && new_opd != subst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 if (subst == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 subst = new_opd;
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 // no simplification possible
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 phi->set(Phi::cannot_simplify);
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 phi->clear(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2474
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 // sucessfully simplified phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 assert(subst != NULL, "illegal phi function");
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 _has_substitutions = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 phi->clear(Phi::visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 phi->set_subst(subst);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 if (PrintPhiFunctions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 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
2484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2486
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 return subst;
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2490
a61af66fc99e Initial load
duke
parents:
diff changeset
2491
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 void PhiSimplifier::block_do(BlockBegin* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 for_each_phi_fun(b, phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 simplify(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2496
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 for_each_phi_fun(b, phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 assert(phi->operand_count() != 1 || phi->subst() != phi, "missed trivial simplification");
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2501
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 ValueStack* state = b->state()->caller_state();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2503 for_each_state_value(state, value,
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2504 Phi* phi = value->as_Phi();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2505 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
2506 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2509
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 // This method is called after all blocks are filled with HIR instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 // It eliminates all Phi functions of the form x = [y, y] and x = [y, x]
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 void GraphBuilder::eliminate_redundant_phis(BlockBegin* start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 PhiSimplifier simplifier(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2515
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 void GraphBuilder::connect_to_end(BlockBegin* beg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 // setup iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 _block = beg;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2521 _state = beg->state()->copy_for_parsing();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 _last = beg;
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 iterate_bytecodes_for_block(beg->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2525
a61af66fc99e Initial load
duke
parents:
diff changeset
2526
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 BlockEnd* GraphBuilder::iterate_bytecodes_for_block(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 if (PrintIRDuringConstruction) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 InstructionPrinter ip;
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 ip.print_instr(_block); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 ip.print_stack(_block->state()); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 ip.print_inline_level(_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 ip.print_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 tty->print_cr("locals size: %d stack size: %d", state()->locals_size(), state()->stack_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 _skip_block = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 assert(state() != NULL, "ValueStack missing!");
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2541 CompileLog* log = compilation()->log();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 ciBytecodeStream s(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 s.reset_to_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 int prev_bci = bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 scope_data()->set_stream(&s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // iterate
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 Bytecodes::Code code = Bytecodes::_illegal;
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 bool push_exception = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2549
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 if (block()->is_set(BlockBegin::exception_entry_flag) && block()->next() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // first thing in the exception entry block should be the exception object.
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 push_exception = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2554
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 while (!bailed_out() && last()->as_BlockEnd() == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 (code = stream()->next()) != ciBytecodeStream::EOBC() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2558 assert(state()->kind() == ValueStack::Parsing, "invalid state kind");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2559
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2560 if (log != NULL)
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2561 log->set_context("bc code='%d' bci='%d'", (int)code, s.cur_bci());
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2562
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 // Check for active jsr during OSR compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 if (compilation()->is_osr_compile()
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 && scope()->is_top_scope()
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 && parsing_jsr()
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 && s.cur_bci() == compilation()->osr_bci()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 bailout("OSR not supported while a jsr is active");
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2570
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 if (push_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 apush(append(new ExceptionObject()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 push_exception = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2575
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 // handle bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 case Bytecodes::_nop : /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 case Bytecodes::_aconst_null : apush(append(new Constant(objectNull ))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 case Bytecodes::_iconst_m1 : ipush(append(new Constant(new IntConstant (-1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 case Bytecodes::_iconst_0 : ipush(append(new Constant(intZero ))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 case Bytecodes::_iconst_1 : ipush(append(new Constant(intOne ))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 case Bytecodes::_iconst_2 : ipush(append(new Constant(new IntConstant ( 2)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 case Bytecodes::_iconst_3 : ipush(append(new Constant(new IntConstant ( 3)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 case Bytecodes::_iconst_4 : ipush(append(new Constant(new IntConstant ( 4)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 case Bytecodes::_iconst_5 : ipush(append(new Constant(new IntConstant ( 5)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 case Bytecodes::_lconst_0 : lpush(append(new Constant(new LongConstant ( 0)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 case Bytecodes::_lconst_1 : lpush(append(new Constant(new LongConstant ( 1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 case Bytecodes::_fconst_0 : fpush(append(new Constant(new FloatConstant ( 0)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 case Bytecodes::_fconst_1 : fpush(append(new Constant(new FloatConstant ( 1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 case Bytecodes::_fconst_2 : fpush(append(new Constant(new FloatConstant ( 2)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 case Bytecodes::_dconst_0 : dpush(append(new Constant(new DoubleConstant( 0)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 case Bytecodes::_dconst_1 : dpush(append(new Constant(new DoubleConstant( 1)))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 case Bytecodes::_bipush : ipush(append(new Constant(new IntConstant(((signed char*)s.cur_bcp())[1])))); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 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
2596 case Bytecodes::_ldc : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 case Bytecodes::_ldc_w : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 case Bytecodes::_ldc2_w : load_constant(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 case Bytecodes::_iload : load_local(intType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 case Bytecodes::_lload : load_local(longType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 case Bytecodes::_fload : load_local(floatType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 case Bytecodes::_dload : load_local(doubleType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 case Bytecodes::_aload : load_local(instanceType, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 case Bytecodes::_iload_0 : load_local(intType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 case Bytecodes::_iload_1 : load_local(intType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 case Bytecodes::_iload_2 : load_local(intType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 case Bytecodes::_iload_3 : load_local(intType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 case Bytecodes::_lload_0 : load_local(longType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 case Bytecodes::_lload_1 : load_local(longType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 case Bytecodes::_lload_2 : load_local(longType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 case Bytecodes::_lload_3 : load_local(longType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 case Bytecodes::_fload_0 : load_local(floatType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 case Bytecodes::_fload_1 : load_local(floatType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 case Bytecodes::_fload_2 : load_local(floatType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 case Bytecodes::_fload_3 : load_local(floatType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 case Bytecodes::_dload_0 : load_local(doubleType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 case Bytecodes::_dload_1 : load_local(doubleType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 case Bytecodes::_dload_2 : load_local(doubleType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 case Bytecodes::_dload_3 : load_local(doubleType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 case Bytecodes::_aload_0 : load_local(objectType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 case Bytecodes::_aload_1 : load_local(objectType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 case Bytecodes::_aload_2 : load_local(objectType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 case Bytecodes::_aload_3 : load_local(objectType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 case Bytecodes::_iaload : load_indexed(T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 case Bytecodes::_laload : load_indexed(T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 case Bytecodes::_faload : load_indexed(T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 case Bytecodes::_daload : load_indexed(T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 case Bytecodes::_aaload : load_indexed(T_OBJECT); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 case Bytecodes::_baload : load_indexed(T_BYTE ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 case Bytecodes::_caload : load_indexed(T_CHAR ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 case Bytecodes::_saload : load_indexed(T_SHORT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 case Bytecodes::_istore : store_local(intType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 case Bytecodes::_lstore : store_local(longType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 case Bytecodes::_fstore : store_local(floatType , s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 case Bytecodes::_dstore : store_local(doubleType, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 case Bytecodes::_astore : store_local(objectType, s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 case Bytecodes::_istore_0 : store_local(intType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 case Bytecodes::_istore_1 : store_local(intType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 case Bytecodes::_istore_2 : store_local(intType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 case Bytecodes::_istore_3 : store_local(intType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 case Bytecodes::_lstore_0 : store_local(longType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 case Bytecodes::_lstore_1 : store_local(longType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 case Bytecodes::_lstore_2 : store_local(longType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 case Bytecodes::_lstore_3 : store_local(longType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 case Bytecodes::_fstore_0 : store_local(floatType , 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 case Bytecodes::_fstore_1 : store_local(floatType , 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 case Bytecodes::_fstore_2 : store_local(floatType , 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 case Bytecodes::_fstore_3 : store_local(floatType , 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 case Bytecodes::_dstore_0 : store_local(doubleType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 case Bytecodes::_dstore_1 : store_local(doubleType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 case Bytecodes::_dstore_2 : store_local(doubleType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 case Bytecodes::_dstore_3 : store_local(doubleType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 case Bytecodes::_astore_0 : store_local(objectType, 0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 case Bytecodes::_astore_1 : store_local(objectType, 1); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 case Bytecodes::_astore_2 : store_local(objectType, 2); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 case Bytecodes::_astore_3 : store_local(objectType, 3); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 case Bytecodes::_iastore : store_indexed(T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 case Bytecodes::_lastore : store_indexed(T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 case Bytecodes::_fastore : store_indexed(T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 case Bytecodes::_dastore : store_indexed(T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 case Bytecodes::_aastore : store_indexed(T_OBJECT); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 case Bytecodes::_bastore : store_indexed(T_BYTE ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 case Bytecodes::_castore : store_indexed(T_CHAR ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 case Bytecodes::_sastore : store_indexed(T_SHORT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 case Bytecodes::_pop : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 case Bytecodes::_pop2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 case Bytecodes::_dup : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 case Bytecodes::_dup_x1 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 case Bytecodes::_dup_x2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 case Bytecodes::_dup2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 case Bytecodes::_dup2_x1 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 case Bytecodes::_dup2_x2 : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 case Bytecodes::_swap : stack_op(code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 case Bytecodes::_iadd : arithmetic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 case Bytecodes::_ladd : arithmetic_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 case Bytecodes::_fadd : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 case Bytecodes::_dadd : arithmetic_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 case Bytecodes::_isub : arithmetic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 case Bytecodes::_lsub : arithmetic_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 case Bytecodes::_fsub : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 case Bytecodes::_dsub : arithmetic_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 case Bytecodes::_imul : arithmetic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 case Bytecodes::_lmul : arithmetic_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 case Bytecodes::_fmul : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 case Bytecodes::_dmul : arithmetic_op(doubleType, code); break;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2686 case Bytecodes::_idiv : arithmetic_op(intType , code, copy_state_for_exception()); break;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2687 case Bytecodes::_ldiv : arithmetic_op(longType , code, copy_state_for_exception()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 case Bytecodes::_fdiv : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 case Bytecodes::_ddiv : arithmetic_op(doubleType, code); break;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2690 case Bytecodes::_irem : arithmetic_op(intType , code, copy_state_for_exception()); break;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2691 case Bytecodes::_lrem : arithmetic_op(longType , code, copy_state_for_exception()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 case Bytecodes::_frem : arithmetic_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 case Bytecodes::_drem : arithmetic_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 case Bytecodes::_ineg : negate_op(intType ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 case Bytecodes::_lneg : negate_op(longType ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 case Bytecodes::_fneg : negate_op(floatType ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 case Bytecodes::_dneg : negate_op(doubleType); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 case Bytecodes::_ishl : shift_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 case Bytecodes::_lshl : shift_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 case Bytecodes::_ishr : shift_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 case Bytecodes::_lshr : shift_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 case Bytecodes::_iushr : shift_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 case Bytecodes::_lushr : shift_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 case Bytecodes::_iand : logic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 case Bytecodes::_land : logic_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 case Bytecodes::_ior : logic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 case Bytecodes::_lor : logic_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 case Bytecodes::_ixor : logic_op(intType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 case Bytecodes::_lxor : logic_op(longType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 case Bytecodes::_iinc : increment(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 case Bytecodes::_i2l : convert(code, T_INT , T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 case Bytecodes::_i2f : convert(code, T_INT , T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 case Bytecodes::_i2d : convert(code, T_INT , T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 case Bytecodes::_l2i : convert(code, T_LONG , T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 case Bytecodes::_l2f : convert(code, T_LONG , T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 case Bytecodes::_l2d : convert(code, T_LONG , T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 case Bytecodes::_f2i : convert(code, T_FLOAT , T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 case Bytecodes::_f2l : convert(code, T_FLOAT , T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 case Bytecodes::_f2d : convert(code, T_FLOAT , T_DOUBLE); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 case Bytecodes::_d2i : convert(code, T_DOUBLE, T_INT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 case Bytecodes::_d2l : convert(code, T_DOUBLE, T_LONG ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 case Bytecodes::_d2f : convert(code, T_DOUBLE, T_FLOAT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 case Bytecodes::_i2b : convert(code, T_INT , T_BYTE ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 case Bytecodes::_i2c : convert(code, T_INT , T_CHAR ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 case Bytecodes::_i2s : convert(code, T_INT , T_SHORT ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 case Bytecodes::_lcmp : compare_op(longType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 case Bytecodes::_fcmpl : compare_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 case Bytecodes::_fcmpg : compare_op(floatType , code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 case Bytecodes::_dcmpl : compare_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 case Bytecodes::_dcmpg : compare_op(doubleType, code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 case Bytecodes::_ifeq : if_zero(intType , If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 case Bytecodes::_ifne : if_zero(intType , If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 case Bytecodes::_iflt : if_zero(intType , If::lss); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 case Bytecodes::_ifge : if_zero(intType , If::geq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 case Bytecodes::_ifgt : if_zero(intType , If::gtr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 case Bytecodes::_ifle : if_zero(intType , If::leq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 case Bytecodes::_if_icmpeq : if_same(intType , If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 case Bytecodes::_if_icmpne : if_same(intType , If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 case Bytecodes::_if_icmplt : if_same(intType , If::lss); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 case Bytecodes::_if_icmpge : if_same(intType , If::geq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 case Bytecodes::_if_icmpgt : if_same(intType , If::gtr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 case Bytecodes::_if_icmple : if_same(intType , If::leq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 case Bytecodes::_if_acmpeq : if_same(objectType, If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 case Bytecodes::_if_acmpne : if_same(objectType, If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 case Bytecodes::_goto : _goto(s.cur_bci(), s.get_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 case Bytecodes::_jsr : jsr(s.get_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 case Bytecodes::_ret : ret(s.get_index()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 case Bytecodes::_tableswitch : table_switch(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 case Bytecodes::_lookupswitch : lookup_switch(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 case Bytecodes::_ireturn : method_return(ipop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 case Bytecodes::_lreturn : method_return(lpop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 case Bytecodes::_freturn : method_return(fpop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 case Bytecodes::_dreturn : method_return(dpop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 case Bytecodes::_areturn : method_return(apop()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 case Bytecodes::_return : method_return(NULL ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 case Bytecodes::_getstatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 case Bytecodes::_putstatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 case Bytecodes::_getfield : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 case Bytecodes::_putfield : access_field(code); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 case Bytecodes::_invokevirtual : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 case Bytecodes::_invokespecial : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 case Bytecodes::_invokestatic : // fall through
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 470
diff changeset
2763 case Bytecodes::_invokedynamic : // fall through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 case Bytecodes::_invokeinterface: invoke(code); break;
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1540
diff changeset
2765 case Bytecodes::_new : new_instance(s.get_index_u2()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 case Bytecodes::_newarray : new_type_array(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 case Bytecodes::_anewarray : new_object_array(); break;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2768 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
2769 case Bytecodes::_athrow : throw_op(s.cur_bci()); break;
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1540
diff changeset
2770 case Bytecodes::_checkcast : check_cast(s.get_index_u2()); break;
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1540
diff changeset
2771 case Bytecodes::_instanceof : instance_of(s.get_index_u2()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 case Bytecodes::_monitorenter : monitorenter(apop(), s.cur_bci()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 case Bytecodes::_monitorexit : monitorexit (apop(), s.cur_bci()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 case Bytecodes::_wide : ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 case Bytecodes::_multianewarray : new_multi_array(s.cur_bcp()[3]); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 case Bytecodes::_ifnull : if_null(objectType, If::eql); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 case Bytecodes::_ifnonnull : if_null(objectType, If::neq); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 case Bytecodes::_goto_w : _goto(s.cur_bci(), s.get_far_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 case Bytecodes::_jsr_w : jsr(s.get_far_dest()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 case Bytecodes::_breakpoint : BAILOUT_("concurrent setting of breakpoint", NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 default : ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 }
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2783
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2784 if (log != NULL)
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2785 log->clear_context(); // skip marker if nothing was printed
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2786
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 // save current bci to setup Goto at the end
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 prev_bci = s.cur_bci();
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
2789
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 CHECK_BAILOUT_(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 // stop processing of this block (see try_inline_full)
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 if (_skip_block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 _skip_block = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 assert(_last && _last->as_BlockEnd(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 return _last->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 // if there are any, check if last instruction is a BlockEnd instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 BlockEnd* end = last()->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 if (end == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 // all blocks must end with a BlockEnd instruction => add a Goto
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 end = new Goto(block_at(s.cur_bci()), false);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2803 append(end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 assert(end == last()->as_BlockEnd(), "inconsistency");
a61af66fc99e Initial load
duke
parents:
diff changeset
2806
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2807 assert(end->state() != NULL, "state must already be present");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2808 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
2809
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // connect to begin & set state
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // NOTE that inlining may have changed the block we are parsing
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 block()->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // propagate state
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 for (int i = end->number_of_sux() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 BlockBegin* sux = end->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 assert(sux->is_predecessor(block()), "predecessor missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 // be careful, bailout if bytecodes are strange
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2818 if (!sux->try_merge(end->state())) BAILOUT_("block join failed", NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 scope_data()->add_to_work_list(end->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2821
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2823
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // done
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 return end;
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 void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 if (start_in_current_block_for_inlining && !bailed_out()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 iterate_bytecodes_for_block(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 start_in_current_block_for_inlining = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 BlockBegin* b;
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 while ((b = scope_data()->remove_from_work_list()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 if (!b->is_set(BlockBegin::was_visited_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 if (b->is_set(BlockBegin::osr_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 // we're about to parse the osr entry block, so make sure
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 // we setup the OSR edge leading into this block so that
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 // Phis get setup correctly.
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 setup_osr_entry_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 // this is no longer the osr entry block, so clear it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 b->clear(BlockBegin::osr_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 b->set(BlockBegin::was_visited_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 connect_to_end(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 } while (!bailed_out() && !scope_data()->is_work_list_empty());
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2853
a61af66fc99e Initial load
duke
parents:
diff changeset
2854
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 bool GraphBuilder::_can_trap [Bytecodes::number_of_java_codes];
a61af66fc99e Initial load
duke
parents:
diff changeset
2856
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 void GraphBuilder::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // the following bytecodes are assumed to potentially
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 // throw exceptions in compiled code - note that e.g.
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 // monitorexit & the return bytecodes do not throw
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 // exceptions since monitor pairing proved that they
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 // succeed (if monitor pairing succeeded)
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 Bytecodes::Code can_trap_list[] =
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 { Bytecodes::_ldc
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 , Bytecodes::_ldc_w
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 , Bytecodes::_ldc2_w
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 , Bytecodes::_iaload
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 , Bytecodes::_laload
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 , Bytecodes::_faload
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 , Bytecodes::_daload
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 , Bytecodes::_aaload
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 , Bytecodes::_baload
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 , Bytecodes::_caload
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 , Bytecodes::_saload
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 , Bytecodes::_iastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 , Bytecodes::_lastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 , Bytecodes::_fastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 , Bytecodes::_dastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 , Bytecodes::_aastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 , Bytecodes::_bastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 , Bytecodes::_castore
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 , Bytecodes::_sastore
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 , Bytecodes::_idiv
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 , Bytecodes::_ldiv
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 , Bytecodes::_irem
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 , Bytecodes::_lrem
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 , Bytecodes::_getstatic
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 , Bytecodes::_putstatic
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 , Bytecodes::_getfield
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 , Bytecodes::_putfield
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 , Bytecodes::_invokevirtual
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 , Bytecodes::_invokespecial
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 , Bytecodes::_invokestatic
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 470
diff changeset
2894 , Bytecodes::_invokedynamic
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 , Bytecodes::_invokeinterface
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 , Bytecodes::_new
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 , Bytecodes::_newarray
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 , Bytecodes::_anewarray
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 , Bytecodes::_arraylength
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 , Bytecodes::_athrow
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 , Bytecodes::_checkcast
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 , Bytecodes::_instanceof
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 , Bytecodes::_monitorenter
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 , Bytecodes::_multianewarray
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2906
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 // inititialize trap tables
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 for (int i = 0; i < Bytecodes::number_of_java_codes; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 _can_trap[i] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 // set standard trap info
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 for (uint j = 0; j < ARRAY_SIZE(can_trap_list); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 _can_trap[can_trap_list[j]] = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
a61af66fc99e Initial load
duke
parents:
diff changeset
2917
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 BlockBegin* GraphBuilder::header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 assert(entry->is_set(f), "entry/flag mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 // create header block
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 BlockBegin* h = new BlockBegin(entry->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 h->set_depth_first_number(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2923
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 Value l = h;
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 BlockEnd* g = new Goto(entry, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 l->set_next(g, entry->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 h->set_end(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 h->set(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 // setup header block end state
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2930 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
2931 assert(s->stack_is_empty(), "must have empty stack at entry point");
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 g->set_state(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 return h;
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2935
a61af66fc99e Initial load
duke
parents:
diff changeset
2936
a61af66fc99e Initial load
duke
parents:
diff changeset
2937
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 BlockBegin* GraphBuilder::setup_start_block(int osr_bci, BlockBegin* std_entry, BlockBegin* osr_entry, ValueStack* state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 BlockBegin* start = new BlockBegin(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2940
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 // This code eliminates the empty start block at the beginning of
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 // each method. Previously, each method started with the
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 // start-block created below, and this block was followed by the
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 // header block that was always empty. This header block is only
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 // necesary if std_entry is also a backward branch target because
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 // then phi functions may be necessary in the header block. It's
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 // also necessary when profiling so that there's a single block that
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 // can increment the interpreter_invocation_count.
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 BlockBegin* new_header_block;
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2950 if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2951 new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
2952 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 new_header_block = std_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2955
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 // setup start block (root for the IR graph)
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 Base* base =
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 new Base(
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 new_header_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 osr_entry
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 start->set_next(base, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 start->set_end(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 // create & setup state for start block
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2965 start->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
2966 base->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2967
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 if (base->std_entry()->state() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 // setup states for header blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 base->std_entry()->merge(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2972
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 assert(base->std_entry()->state() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2976
a61af66fc99e Initial load
duke
parents:
diff changeset
2977
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 void GraphBuilder::setup_osr_entry_block() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 assert(compilation()->is_osr_compile(), "only for osrs");
a61af66fc99e Initial load
duke
parents:
diff changeset
2980
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 int osr_bci = compilation()->osr_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 ciBytecodeStream s(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 s.reset_to_bci(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 s.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 scope_data()->set_stream(&s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2986
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 // create a new block to be the osr setup code
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 _osr_entry = new BlockBegin(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 _osr_entry->set(BlockBegin::osr_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 _osr_entry->set_depth_first_number(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 BlockBegin* target = bci2block()->at(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 assert(target != NULL && target->is_set(BlockBegin::osr_entry_flag), "must be there");
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 // the osr entry has no values for locals
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 ValueStack* state = target->state()->copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 _osr_entry->set_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2996
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 _block = _osr_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 _state = _osr_entry->state()->copy();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3000 assert(_state->bci() == osr_bci, "mismatch");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 _last = _osr_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 Value e = append(new OsrEntry());
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 e->set_needs_null_check(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3004
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 // OSR buffer is
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 // locals[nlocals-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 // monitors[number_of_locks-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 // locals is a direct copy of the interpreter frame so in the osr buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 // so first slot in the local array is the last local from the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 // and last slot is local[0] (receiver) from the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 // Similarly with locks. The first lock slot in the osr buffer is the nth lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 // in the interpreter frame (the method lock if a sync method)
a61af66fc99e Initial load
duke
parents:
diff changeset
3017
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 // Initialize monitors in the compiled activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3019
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 Value local;
a61af66fc99e Initial load
duke
parents:
diff changeset
3022
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 // find all the locals that the interpreter thinks contain live oops
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 const BitMap live_oops = method()->live_local_oops_at_bci(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3025
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 // compute the offset into the locals so that we can treat the buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // as if the locals were still in the interpreter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 int locals_offset = BytesPerWord * (method()->max_locals() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 for_each_local_value(state, index, local) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 int offset = locals_offset - (index + local->type()->size() - 1) * BytesPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 Value get;
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 if (local->type()->is_object_kind() && !live_oops.at(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 // The interpreter thinks this local is dead but the compiler
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 // doesn't so pretend that the interpreter passed in null.
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 get = append(new Constant(objectNull));
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 get = append(new UnsafeGetRaw(as_BasicType(local->type()), e,
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 append(new Constant(new IntConstant(offset))),
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 0,
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
3040 true /*unaligned*/, true /*wide*/));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 _state->store_local(index, get);
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3044
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 // the storage for the OSR buffer is freed manually in the LIRGenerator.
a61af66fc99e Initial load
duke
parents:
diff changeset
3046
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 assert(state->caller_state() == NULL, "should be top scope");
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 state->clear_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 Goto* g = new Goto(target, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 append(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 _osr_entry->set_end(g);
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 target->merge(_osr_entry->end()->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
3053
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3056
a61af66fc99e Initial load
duke
parents:
diff changeset
3057
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 ValueStack* GraphBuilder::state_at_entry() {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3059 ValueStack* state = new ValueStack(scope(), NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3060
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // Set up locals for receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 int idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 if (!method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 // we should always see the receiver
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2405
diff changeset
3065 state->store_local(idx, new Local(method()->holder(), objectType, idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 idx = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3068
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 // Set up locals for incoming arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 ciSignature* sig = method()->signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 for (int i = 0; i < sig->count(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 ciType* type = sig->type_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 BasicType basic_type = type->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 // don't allow T_ARRAY to propagate into locals types
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 if (basic_type == T_ARRAY) basic_type = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 ValueType* vt = as_ValueType(basic_type);
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2405
diff changeset
3077 state->store_local(idx, new Local(type, vt, idx));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 idx += type->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3080
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 // lock synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 if (method()->is_synchronized()) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3083 state->lock(NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3085
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 return state;
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3088
a61af66fc99e Initial load
duke
parents:
diff changeset
3089
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 : _scope_data(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 , _instruction_count(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 , _osr_entry(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 , _memory(new MemoryBuffer())
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 , _compilation(compilation)
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 , _inline_bailout_msg(NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 int osr_bci = compilation->osr_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
3099
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 // determine entry points and bci2block mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 BlockListBuilder blm(compilation, scope, osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
3103
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 BlockList* bci2block = blm.bci2block();
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 BlockBegin* start_block = bci2block->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3106
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 push_root_scope(scope, bci2block, start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3108
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 // setup state for std entry
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 _initial_state = state_at_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 start_block->merge(_initial_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
3112
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 // complete graph
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 _vmap = new ValueMap();
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 switch (scope->method()->intrinsic_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 case vmIntrinsics::_dabs : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 case vmIntrinsics::_dsqrt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 case vmIntrinsics::_dsin : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 case vmIntrinsics::_dcos : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 case vmIntrinsics::_dtan : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 case vmIntrinsics::_dlog : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 case vmIntrinsics::_dlog10 : // fall through
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3123 case vmIntrinsics::_dexp : // fall through
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3124 case vmIntrinsics::_dpow : // fall through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 // Compiles where the root method is an intrinsic need a special
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 // compilation environment because the bytecodes for the method
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 // shouldn't be parsed during the compilation, only the special
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 // Intrinsic node should be emitted. If this isn't done the the
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 // code for the inlined version will be different than the root
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 // compiled version which could lead to monotonicity problems on
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // intel.
a61af66fc99e Initial load
duke
parents:
diff changeset
3133
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 // Set up a stream so that appending instructions works properly.
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 ciBytecodeStream s(scope->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 s.reset_to_bci(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 scope_data()->set_stream(&s);
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 s.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
3139
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 // setup the initial block state
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 _block = start_block;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3142 _state = start_block->state()->copy_for_parsing();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 _last = start_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 load_local(doubleType, 0);
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3145 if (scope->method()->intrinsic_id() == vmIntrinsics::_dpow) {
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3146 load_local(doubleType, 2);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3147 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3148
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 // Emit the intrinsic node.
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 bool result = try_inline_intrinsics(scope->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 if (!result) BAILOUT("failed to inline intrinsic");
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 method_return(dpop());
a61af66fc99e Initial load
duke
parents:
diff changeset
3153
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 // connect the begin and end blocks and we're all done.
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 BlockEnd* end = last()->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 block()->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 }
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3159
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3160 case vmIntrinsics::_Reference_get:
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3161 {
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3162 {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3163 // 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
3164 // 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
3165 // 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
3166 // 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
3167 // the pre-barrier code.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3168 // 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
3169 // 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
3170 // 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
3171 // 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
3172 // reference processing.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3173
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3174 // Also we need intrinsic to prevent commoning reads from this field
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3175 // across safepoint since GC can change its value.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3176
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3177 // 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
3178 ciBytecodeStream s(scope->method());
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3179 s.reset_to_bci(0);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3180 scope_data()->set_stream(&s);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3181 s.next();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3182
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3183 // setup the initial block state
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3184 _block = start_block;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3185 _state = start_block->state()->copy_for_parsing();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3186 _last = start_block;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3187 load_local(objectType, 0);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3188
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3189 // Emit the intrinsic node.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3190 bool result = try_inline_intrinsics(scope->method());
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3191 if (!result) BAILOUT("failed to inline intrinsic");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3192 method_return(apop());
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3193
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3194 // 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
3195 BlockEnd* end = last()->as_BlockEnd();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3196 block()->set_end(end);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3197 break;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3198 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3199 // Otherwise, fall thru
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3200 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3201
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 scope_data()->add_to_work_list(start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 iterate_all_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
3208
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 _start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
3210
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 eliminate_redundant_phis(_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
3212
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 NOT_PRODUCT(if (PrintValueNumbering && Verbose) print_stats());
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 // for osr compile, bailout if some requirements are not fulfilled
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 if (osr_bci != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 BlockBegin* osr_block = blm.bci2block()->at(osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 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
3218
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 // 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
3220 if (!osr_block->state()->stack_is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 BAILOUT("stack not empty at OSR entry point");
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 if (PrintCompilation && Verbose) tty->print_cr("Created %d Instructions", _instruction_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3228
a61af66fc99e Initial load
duke
parents:
diff changeset
3229
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3230 ValueStack* GraphBuilder::copy_state_before() {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3231 return copy_state_before_with_bci(bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3232 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3233
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3234 ValueStack* GraphBuilder::copy_state_exhandling() {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3235 return copy_state_exhandling_with_bci(bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3236 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3237
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3238 ValueStack* GraphBuilder::copy_state_for_exception() {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3239 return copy_state_for_exception_with_bci(bci());
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3240 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3241
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3242 ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3243 return state()->copy(ValueStack::StateBefore, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3245
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3246 ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3247 if (!has_handler()) return NULL;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3248 return state()->copy(ValueStack::StateBefore, bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3249 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3250
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3251 ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3252 ValueStack* s = copy_state_exhandling_with_bci(bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3253 if (s == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3254 if (_compilation->env()->jvmti_can_access_local_variables()) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3255 s = state()->copy(ValueStack::ExceptionState, bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3256 } else {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3257 s = state()->copy(ValueStack::EmptyExceptionState, bci);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3258 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3259 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3260 return s;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3261 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3262
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 int recur_level = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 for (IRScope* s = scope(); s != NULL; s = s->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 if (s->method() == cur_callee) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 ++recur_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 return recur_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3272
a61af66fc99e Initial load
duke
parents:
diff changeset
3273
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3274 bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3275 const char* msg = NULL;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3276
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3277 // clear out any existing inline bailout condition
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 clear_inline_bailout();
a61af66fc99e Initial load
duke
parents:
diff changeset
3279
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3280 // exclude methods we don't want to inline
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3281 msg = should_not_inline(callee);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3282 if (msg != NULL) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3283 print_inlining(callee, msg, /*success*/ false);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3284 return false;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3285 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3286
6892
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
3287 // method handle invokes
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
3288 if (callee->is_method_handle_intrinsic()) {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
3289 return try_method_handle_inline(callee);
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
3290 }
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
3291
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3292 // handle intrinsics
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3293 if (callee->intrinsic_id() != vmIntrinsics::_none) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3294 if (try_inline_intrinsics(callee)) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3295 print_inlining(callee, "intrinsic");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3296 return true;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3297 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3298 // try normal inlining
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3299 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3300
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3301 // certain methods cannot be parsed at all
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3302 msg = check_can_parse(callee);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3303 if (msg != NULL) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3304 print_inlining(callee, msg, /*success*/ false);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3305 return false;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3306 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3307
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3308 // If bytecode not set use the current one.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3309 if (bc == Bytecodes::_illegal) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3310 bc = code();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3311 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3312 if (try_inline_full(callee, holder_known, bc, receiver))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 return true;
7603
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3314
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3315 // Entire compilation could fail during try_inline_full call.
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3316 // In that case printing inlining decision info is useless.
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3317 if (!bailed_out())
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3318 print_inlining(callee, _inline_bailout_msg, /*success*/ false);
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3319
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3320 return false;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3321 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3322
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3323
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3324 const char* GraphBuilder::check_can_parse(ciMethod* callee) const {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3325 // Certain methods cannot be parsed at all:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3326 if ( callee->is_native()) return "native method";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3327 if ( callee->is_abstract()) return "abstract method";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3328 if (!callee->can_be_compiled()) return "not compilable (disabled)";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3329 return NULL;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3330 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3331
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3332
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3333 // negative filter: should callee NOT be inlined? returns NULL, ok to inline, or rejection msg
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3334 const char* GraphBuilder::should_not_inline(ciMethod* callee) const {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3335 if ( callee->should_exclude()) return "excluded by CompilerOracle";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3336 if ( callee->should_not_inline()) return "disallowed by CompilerOracle";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3337 if ( callee->dont_inline()) return "don't inline by annotation";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3338 return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3340
a61af66fc99e Initial load
duke
parents:
diff changeset
3341
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
1540
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3343 if (callee->is_synchronized()) {
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3344 // 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
3345 return false;
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3346 }
99791ad65936 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 1397
diff changeset
3347
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 // callee seems like a good candidate
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 // determine id
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3350 vmIntrinsics::ID id = callee->intrinsic_id();
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3351 if (!InlineNatives && id != vmIntrinsics::_Reference_get) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3352 // InlineNatives does not control Reference.get
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3353 INLINE_BAILOUT("intrinsic method inlining disabled");
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3354 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 bool preserves_state = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 bool cantrap = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 switch (id) {
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3358 case vmIntrinsics::_arraycopy:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 if (!InlineArrayCopy) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3361
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3362 #ifdef TRACE_HAVE_INTRINSICS
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3363 case vmIntrinsics::_classID:
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3364 case vmIntrinsics::_threadID:
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3365 preserves_state = true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3366 cantrap = true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3367 break;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3368
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3369 case vmIntrinsics::_counterTime:
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3370 preserves_state = true;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3371 cantrap = false;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3372 break;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3373 #endif
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 5998
diff changeset
3374
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 case vmIntrinsics::_currentTimeMillis:
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 case vmIntrinsics::_nanoTime:
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3380
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 case vmIntrinsics::_floatToRawIntBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 case vmIntrinsics::_intBitsToFloat :
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 case vmIntrinsics::_doubleToRawLongBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 case vmIntrinsics::_longBitsToDouble :
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 if (!InlineMathNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3389
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 case vmIntrinsics::_getClass :
6135
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
3391 case vmIntrinsics::_isInstance :
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 if (!InlineClassNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3395
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 case vmIntrinsics::_currentThread :
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 if (!InlineThreadNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3401
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 case vmIntrinsics::_dabs : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 case vmIntrinsics::_dsqrt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 case vmIntrinsics::_dsin : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 case vmIntrinsics::_dcos : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 case vmIntrinsics::_dtan : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 case vmIntrinsics::_dlog : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 case vmIntrinsics::_dlog10 : // fall through
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3409 case vmIntrinsics::_dexp : // fall through
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3410 case vmIntrinsics::_dpow : // fall through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 if (!InlineMathNatives) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 cantrap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3415
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 // Use special nodes for Unsafe instructions so we can more easily
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 // perform an address-mode optimization on the raw variants
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 case vmIntrinsics::_getObject : return append_unsafe_get_obj(callee, T_OBJECT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 case vmIntrinsics::_getBoolean: return append_unsafe_get_obj(callee, T_BOOLEAN, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 case vmIntrinsics::_getByte : return append_unsafe_get_obj(callee, T_BYTE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 case vmIntrinsics::_getShort : return append_unsafe_get_obj(callee, T_SHORT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 case vmIntrinsics::_getChar : return append_unsafe_get_obj(callee, T_CHAR, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 case vmIntrinsics::_getInt : return append_unsafe_get_obj(callee, T_INT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 case vmIntrinsics::_getLong : return append_unsafe_get_obj(callee, T_LONG, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 case vmIntrinsics::_getFloat : return append_unsafe_get_obj(callee, T_FLOAT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 case vmIntrinsics::_getDouble : return append_unsafe_get_obj(callee, T_DOUBLE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3427
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 case vmIntrinsics::_putObject : return append_unsafe_put_obj(callee, T_OBJECT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 case vmIntrinsics::_putBoolean: return append_unsafe_put_obj(callee, T_BOOLEAN, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 case vmIntrinsics::_putByte : return append_unsafe_put_obj(callee, T_BYTE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 case vmIntrinsics::_putShort : return append_unsafe_put_obj(callee, T_SHORT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 case vmIntrinsics::_putChar : return append_unsafe_put_obj(callee, T_CHAR, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 case vmIntrinsics::_putInt : return append_unsafe_put_obj(callee, T_INT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 case vmIntrinsics::_putLong : return append_unsafe_put_obj(callee, T_LONG, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 case vmIntrinsics::_putFloat : return append_unsafe_put_obj(callee, T_FLOAT, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 case vmIntrinsics::_putDouble : return append_unsafe_put_obj(callee, T_DOUBLE, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3437
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 case vmIntrinsics::_getObjectVolatile : return append_unsafe_get_obj(callee, T_OBJECT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 case vmIntrinsics::_getBooleanVolatile: return append_unsafe_get_obj(callee, T_BOOLEAN, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 case vmIntrinsics::_getByteVolatile : return append_unsafe_get_obj(callee, T_BYTE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 case vmIntrinsics::_getShortVolatile : return append_unsafe_get_obj(callee, T_SHORT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 case vmIntrinsics::_getCharVolatile : return append_unsafe_get_obj(callee, T_CHAR, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 case vmIntrinsics::_getIntVolatile : return append_unsafe_get_obj(callee, T_INT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 case vmIntrinsics::_getLongVolatile : return append_unsafe_get_obj(callee, T_LONG, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 case vmIntrinsics::_getFloatVolatile : return append_unsafe_get_obj(callee, T_FLOAT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 case vmIntrinsics::_getDoubleVolatile : return append_unsafe_get_obj(callee, T_DOUBLE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3447
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 case vmIntrinsics::_putObjectVolatile : return append_unsafe_put_obj(callee, T_OBJECT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 case vmIntrinsics::_putBooleanVolatile: return append_unsafe_put_obj(callee, T_BOOLEAN, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 case vmIntrinsics::_putByteVolatile : return append_unsafe_put_obj(callee, T_BYTE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 case vmIntrinsics::_putShortVolatile : return append_unsafe_put_obj(callee, T_SHORT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 case vmIntrinsics::_putCharVolatile : return append_unsafe_put_obj(callee, T_CHAR, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 case vmIntrinsics::_putIntVolatile : return append_unsafe_put_obj(callee, T_INT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 case vmIntrinsics::_putLongVolatile : return append_unsafe_put_obj(callee, T_LONG, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 case vmIntrinsics::_putFloatVolatile : return append_unsafe_put_obj(callee, T_FLOAT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 case vmIntrinsics::_putDoubleVolatile : return append_unsafe_put_obj(callee, T_DOUBLE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3457
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 case vmIntrinsics::_getByte_raw : return append_unsafe_get_raw(callee, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 case vmIntrinsics::_getShort_raw : return append_unsafe_get_raw(callee, T_SHORT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 case vmIntrinsics::_getChar_raw : return append_unsafe_get_raw(callee, T_CHAR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 case vmIntrinsics::_getInt_raw : return append_unsafe_get_raw(callee, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 case vmIntrinsics::_getLong_raw : return append_unsafe_get_raw(callee, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 case vmIntrinsics::_getFloat_raw : return append_unsafe_get_raw(callee, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 case vmIntrinsics::_getDouble_raw : return append_unsafe_get_raw(callee, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3465
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 case vmIntrinsics::_putByte_raw : return append_unsafe_put_raw(callee, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 case vmIntrinsics::_putShort_raw : return append_unsafe_put_raw(callee, T_SHORT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 case vmIntrinsics::_putChar_raw : return append_unsafe_put_raw(callee, T_CHAR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 case vmIntrinsics::_putInt_raw : return append_unsafe_put_raw(callee, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 case vmIntrinsics::_putLong_raw : return append_unsafe_put_raw(callee, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 case vmIntrinsics::_putFloat_raw : return append_unsafe_put_raw(callee, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 case vmIntrinsics::_putDouble_raw : return append_unsafe_put_raw(callee, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3473
a61af66fc99e Initial load
duke
parents:
diff changeset
3474 case vmIntrinsics::_prefetchRead : return append_unsafe_prefetch(callee, false, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 case vmIntrinsics::_prefetchWrite : return append_unsafe_prefetch(callee, false, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 case vmIntrinsics::_prefetchReadStatic : return append_unsafe_prefetch(callee, true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 case vmIntrinsics::_prefetchWriteStatic : return append_unsafe_prefetch(callee, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3478
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 case vmIntrinsics::_checkIndex :
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 if (!InlineNIOCheckIndex) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 preserves_state = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 case vmIntrinsics::_putOrderedObject : return append_unsafe_put_obj(callee, T_OBJECT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 case vmIntrinsics::_putOrderedInt : return append_unsafe_put_obj(callee, T_INT, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 case vmIntrinsics::_putOrderedLong : return append_unsafe_put_obj(callee, T_LONG, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3486
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 case vmIntrinsics::_compareAndSwapLong:
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 if (!VM_Version::supports_cx8()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 case vmIntrinsics::_compareAndSwapInt:
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 case vmIntrinsics::_compareAndSwapObject:
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 append_unsafe_CAS(callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3494
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3495 case vmIntrinsics::_getAndAddInt:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3496 if (!VM_Version::supports_atomic_getadd4()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3497 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3498 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3499 return append_unsafe_get_and_set_obj(callee, true);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3500 case vmIntrinsics::_getAndAddLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3501 if (!VM_Version::supports_atomic_getadd8()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3502 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3503 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3504 return append_unsafe_get_and_set_obj(callee, true);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3505 case vmIntrinsics::_getAndSetInt:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3506 if (!VM_Version::supports_atomic_getset4()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3507 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3508 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3509 return append_unsafe_get_and_set_obj(callee, false);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3510 case vmIntrinsics::_getAndSetLong:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3511 if (!VM_Version::supports_atomic_getset8()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3512 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3513 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3514 return append_unsafe_get_and_set_obj(callee, false);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3515 case vmIntrinsics::_getAndSetObject:
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3516 #ifdef _LP64
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3517 if (!UseCompressedOops && !VM_Version::supports_atomic_getset8()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3518 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3519 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3520 if (UseCompressedOops && !VM_Version::supports_atomic_getset4()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3521 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3522 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3523 #else
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3524 if (!VM_Version::supports_atomic_getset4()) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3525 return false;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3526 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3527 #endif
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3528 return append_unsafe_get_and_set_obj(callee, false);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
3529
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3530 case vmIntrinsics::_Reference_get:
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3531 // Use the intrinsic version of Reference.get() so that the value in
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3532 // the referent field can be registered by the G1 pre-barrier code.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3533 // Also to prevent commoning reads from this field across safepoint
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6267
diff changeset
3534 // since GC can change its value.
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3535 preserves_state = true;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3536 break;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2376
diff changeset
3537
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3538 case vmIntrinsics::_updateCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3539 case vmIntrinsics::_updateBytesCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3540 case vmIntrinsics::_updateByteBufferCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3541 if (!UseCRC32Intrinsics) return false;
11264
7894695caee6 disabled CRC32 intrinsics under client compiler with jdk version earlier than 8 (GRAAL-409)
Doug Simon <doug.simon@oracle.com>
parents: 11080
diff changeset
3542 // GRAAL-409: CRC32 C1 intrinsics cause errors on jdk version earlier than 8
7894695caee6 disabled CRC32 intrinsics under client compiler with jdk version earlier than 8 (GRAAL-409)
Doug Simon <doug.simon@oracle.com>
parents: 11080
diff changeset
3543 if (!JDK_Version::is_gte_jdk18x_version()) return false;
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3544 cantrap = false;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3545 preserves_state = true;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3546 break;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 8860
diff changeset
3547
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6973
diff changeset
3548 case vmIntrinsics::_loadFence :
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6973
diff changeset
3549 case vmIntrinsics::_storeFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6973
diff changeset
3550 case vmIntrinsics::_fullFence :
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6973
diff changeset
3551 break;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6973
diff changeset
3552
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 default : return false; // do not inline
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 // create intrinsic node
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 const bool has_receiver = !callee->is_static();
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 ValueType* result_type = as_ValueType(callee->return_type());
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3558 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3559
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 Values* args = state()->pop_arguments(callee->arg_size());
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3561
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3562 if (is_profiling()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 // Don't profile in the special case where the root method
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 // is the intrinsic
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 if (callee != method()) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3566 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3567 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3568 if (profile_calls()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3569 Value recv = NULL;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3570 if (has_receiver) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3571 recv = args->at(0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3572 null_check(recv);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3573 }
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
3574 profile_call(callee, recv, NULL, collect_args_for_profiling(args, callee, true), true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3578
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3579 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 preserves_state, cantrap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 // append instruction & push result
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 Value value = append_split(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 if (result_type != voidType) push(result_type, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
3584
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
3585 if (callee != method() && profile_return() && result_type->is_object_kind()) {
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3586 profile_return_type(result, callee);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3587 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3588
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 // done
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3592
a61af66fc99e Initial load
duke
parents:
diff changeset
3593
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 // Introduce a new callee continuation point - all Ret instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 // will be replaced with Gotos to this point.
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 BlockBegin* cont = block_at(next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr");
a61af66fc99e Initial load
duke
parents:
diff changeset
3599
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 // Note: can not assign state to continuation yet, as we have to
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 // pick up the state from the Ret instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
3602
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 // Push callee scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 push_scope_for_jsr(cont, jsr_dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3605
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 // Temporarily set up bytecode stream so we can append instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 // (only using the bci of this stream)
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 scope_data()->set_stream(scope_data()->parent()->stream());
a61af66fc99e Initial load
duke
parents:
diff changeset
3609
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 BlockBegin* jsr_start_block = block_at(jsr_dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 assert(jsr_start_block != NULL, "jsr start block must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 assert(!jsr_start_block->is_set(BlockBegin::was_visited_flag), "should not have visited jsr yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 Goto* goto_sub = new Goto(jsr_start_block, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 // Must copy state to avoid wrong sharing when parsing bytecodes
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 assert(jsr_start_block->state() == NULL, "should have fresh jsr starting block");
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3616 jsr_start_block->set_state(copy_state_before_with_bci(jsr_dest_bci));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 append(goto_sub);
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 _block->set_end(goto_sub);
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 _last = _block = jsr_start_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3620
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 // Clear out bytecode stream
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3623
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 scope_data()->add_to_work_list(jsr_start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3625
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 // Ready to resume parsing in subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 iterate_all_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3628
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 // If we bailed out during parsing, return immediately (this is bad news)
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 CHECK_BAILOUT_(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3631
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 // Detect whether the continuation can actually be reached. If not,
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 // it has not had state set by the join() operations in
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 // iterate_bytecodes_for_block()/ret() and we should not touch the
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 // iteration state. The calling activation of
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 // iterate_bytecodes_for_block will then complete normally.
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 if (cont->state() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 if (!cont->is_set(BlockBegin::was_visited_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 // add continuation to work list instead of parsing it immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 scope_data()->parent()->add_to_work_list(cont);
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3643
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 assert(jsr_continuation() == cont, "continuation must not have changed");
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 assert(!jsr_continuation()->is_set(BlockBegin::was_visited_flag) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 jsr_continuation()->is_set(BlockBegin::parser_loop_header_flag),
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 "continuation can only be visited in case of backward branches");
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 assert(_last && _last->as_BlockEnd(), "block must have end");
a61af66fc99e Initial load
duke
parents:
diff changeset
3649
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 // continuation is in work list, so end iteration of current block
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 _skip_block = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 pop_scope_for_jsr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3653
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3656
a61af66fc99e Initial load
duke
parents:
diff changeset
3657
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // Inline the entry of a synchronized method as a monitor enter and
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 // register the exception handler which releases the monitor if an
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 // exception is thrown within the callee. Note that the monitor enter
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 // cannot throw an exception itself, because the receiver is
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 // guaranteed to be non-null by the explicit null check at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 // beginning of inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 void GraphBuilder::inline_sync_entry(Value lock, BlockBegin* sync_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 assert(lock != NULL && sync_handler != NULL, "lock or handler missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
3666
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 monitorenter(lock, SynchronizationEntryBCI);
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 assert(_last->as_MonitorEnter() != NULL, "monitor enter expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 _last->set_needs_null_check(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3670
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 sync_handler->set(BlockBegin::exception_entry_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 sync_handler->set(BlockBegin::is_on_work_list_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3673
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 XHandler* h = new XHandler(desc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 h->set_entry_block(sync_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 scope_data()->xhandlers()->append(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 scope_data()->set_has_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3680
a61af66fc99e Initial load
duke
parents:
diff changeset
3681
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // If an exception is thrown and not handled within an inlined
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 // synchronized method, the monitor must be released before the
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // exception is rethrown in the outer scope. Generate the appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // instructions here.
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 BlockBegin* orig_block = _block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 ValueStack* orig_state = _state;
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 Instruction* orig_last = _last;
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 _last = _block = sync_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 _state = sync_handler->state()->copy();
a61af66fc99e Initial load
duke
parents:
diff changeset
3692
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 assert(sync_handler != NULL, "handler missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 assert(!sync_handler->is_set(BlockBegin::was_visited_flag), "is visited here");
a61af66fc99e Initial load
duke
parents:
diff changeset
3695
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 assert(lock != NULL || default_handler, "lock or handler missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
3697
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 XHandler* h = scope_data()->xhandlers()->remove_last();
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 assert(h->entry_block() == sync_handler, "corrupt list of handlers");
a61af66fc99e Initial load
duke
parents:
diff changeset
3700
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 block()->set(BlockBegin::was_visited_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 assert(exception->is_pinned(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
3704
2318
6f3746e69a78 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 2167
diff changeset
3705 int bci = SynchronizationEntryBCI;
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
3706 if (compilation()->env()->dtrace_method_probes()) {
2318
6f3746e69a78 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 2167
diff changeset
3707 // 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
3708 // 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
3709 Values* args = new Values(1);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
3710 args->push(append_with_bci(new Constant(new MethodConstant(method())), bci));
2318
6f3746e69a78 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 2167
diff changeset
3711 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
3712 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
3713
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 if (lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 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
3716 if (!lock->is_linked()) {
2318
6f3746e69a78 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 2167
diff changeset
3717 lock = append_with_bci(lock, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3719
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 // 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
3721 monitorexit(lock, bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3722
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 // exit the context of the synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 if (!default_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 pop_scope();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3726 bci = _state->caller_state()->bci();
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3727 _state = _state->caller_state()->copy_for_parsing();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3730
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 // perform the throw as if at the the call site
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 apush(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 throw_op(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
3734
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 BlockEnd* end = last()->as_BlockEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 block()->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
3737
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 _block = orig_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 _state = orig_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 _last = orig_last;
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3742
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3744 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 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
3746 if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
2c359f27615c 7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents: 3255
diff changeset
3747 INLINE_BAILOUT("inlining prohibited by policy");
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3748 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 // first perform tests of things it's not possible to inline
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 if (callee->has_exception_handlers() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 if (callee->is_synchronized() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 !InlineSynchronizedMethods ) INLINE_BAILOUT("callee is synchronized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 if (!callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 if (!callee->has_balanced_monitors()) INLINE_BAILOUT("callee's monitors do not match");
a61af66fc99e Initial load
duke
parents:
diff changeset
3756
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 // Proper inlining of methods with jsrs requires a little more work.
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
3759
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 // When SSE2 is used on intel, then no special handling is needed
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 // for strictfp because the enum-constant is fixed at compile time,
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 // the check for UseSSE2 is needed here
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 if (strict_fp_requires_explicit_rounding && UseSSE < 2 && method()->is_strict() != callee->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 INLINE_BAILOUT("caller and callee have different strict fp requirements");
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3766
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3767 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
3768 INLINE_BAILOUT("mdo allocation failed");
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3769 }
3844
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3770
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3771 // now perform tests that are based on flag settings
7991
60bba1398c51 8005439: no message about inline method if it specifed by CompileCommand
vlivanov
parents: 7603
diff changeset
3772 if (callee->force_inline()) {
12975
0d1661d63d70 8012941: JSR 292: too deep inlining might crash compiler because of stack overflow
vlivanov
parents: 12962
diff changeset
3773 if (inline_level() > MaxForceInlineLevel) INLINE_BAILOUT("MaxForceInlineLevel");
7991
60bba1398c51 8005439: no message about inline method if it specifed by CompileCommand
vlivanov
parents: 7603
diff changeset
3774 print_inlining(callee, "force inline by annotation");
60bba1398c51 8005439: no message about inline method if it specifed by CompileCommand
vlivanov
parents: 7603
diff changeset
3775 } else if (callee->should_inline()) {
60bba1398c51 8005439: no message about inline method if it specifed by CompileCommand
vlivanov
parents: 7603
diff changeset
3776 print_inlining(callee, "force inline by CompileOracle");
3844
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3777 } else {
7991
60bba1398c51 8005439: no message about inline method if it specifed by CompileCommand
vlivanov
parents: 7603
diff changeset
3778 // use heuristic controls on inlining
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3779 if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("inlining too deep");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3780 if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep");
3897
de847cac9235 7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents: 3844
diff changeset
3781 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
3782
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3783 // 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
3784 if (callee->name() == ciSymbol::object_initializer_name() &&
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3785 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
3786 // Throwable constructor call
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3787 IRScope* top = scope();
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3788 while (top->caller() != NULL) {
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3789 top = top->caller();
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3790 }
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3791 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
3792 INLINE_BAILOUT("don't inline Throwable constructors");
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3793 }
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3794 }
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3795
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3796 if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3797 INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3798 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3799 // printing
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
3800 print_inlining(callee);
3844
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3801 }
ce3e1d4dc416 7060619: C1 should respect inline and dontinline directives from CompilerOracle
never
parents: 3791
diff changeset
3802
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 // NOTE: Bailouts from this point on, which occur at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 // GraphBuilder level, do not cause bailout just of the inlining but
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 // in fact of the entire compilation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3806
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 BlockBegin* orig_block = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
3808
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3809 const bool is_invokedynamic = bc == Bytecodes::_invokedynamic;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3810 const bool has_receiver = (bc != Bytecodes::_invokestatic && !is_invokedynamic);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3811
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 const int args_base = state()->stack_size() - callee->arg_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 assert(args_base >= 0, "stack underflow during inlining");
a61af66fc99e Initial load
duke
parents:
diff changeset
3814
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 // Insert null check if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 Value recv = NULL;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3817 if (has_receiver) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 // note: null check must happen even if first instruction of callee does
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 // an implicit null check since the callee is in a different scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 // and we must make sure exception handling does the right thing
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 assert(!callee->is_static(), "callee must not be static");
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 assert(callee->arg_size() > 0, "must have at least a receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 recv = state()->stack_at(args_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 null_check(recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3826
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3827 if (is_profiling()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3828 // Note that we'd collect profile data in this method if we wanted it.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3829 // this may be redundant here...
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3830 compilation()->set_would_profile(true);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3831
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3832 if (profile_calls()) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3833 int start = 0;
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
3834 Values* obj_args = args_list_for_profiling(callee, start, has_receiver);
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3835 if (obj_args != NULL) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3836 int s = obj_args->size();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3837 // if called through method handle invoke, some arguments may have been popped
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3838 for (int i = args_base+start, j = 0; j < obj_args->size() && i < state()->stack_size(); ) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3839 Value v = state()->stack_at_inc(i);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3840 if (v->type()->is_object_kind()) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3841 obj_args->push(v);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3842 j++;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3843 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3844 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3845 #ifdef ASSERT
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3846 {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3847 bool ignored_will_link;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3848 ciSignature* declared_signature = NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3849 ciMethod* real_target = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3850 assert(s == obj_args->length() || real_target->is_method_handle_intrinsic(), "missed on arg?");
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3851 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3852 #endif
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3853 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
3854 profile_call(callee, recv, holder_known ? callee->holder() : NULL, obj_args, true);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1602
diff changeset
3855 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3857
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 // Introduce a new callee continuation point - if the callee has
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 // more than one return instruction or the return does not allow
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 // fall-through of control flow, all return instructions of the
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 // callee will need to be replaced by Goto's pointing to this
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 // continuation point.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3863 BlockBegin* cont = block_at(next_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 bool continuation_existed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 if (cont == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 cont = new BlockBegin(next_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 // low number so that continuation gets parsed as early as possible
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 cont->set_depth_first_number(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 if (PrintInitialBlockList) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 tty->print_cr("CFG: created block %d (bci %d) as continuation for inline at bci %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 cont->block_id(), cont->bci(), bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 continuation_existed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 // Record number of predecessors of continuation block before
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 // inlining, to detect if inlined method has edges to its
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 // continuation after inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 int continuation_preds = cont->number_of_preds();
a61af66fc99e Initial load
duke
parents:
diff changeset
3881
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 // Push callee scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 push_scope(callee, cont);
a61af66fc99e Initial load
duke
parents:
diff changeset
3884
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 // the BlockListBuilder for the callee could have bailed out
7603
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3886 if (bailed_out())
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3887 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3888
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 // Temporarily set up bytecode stream so we can append instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 // (only using the bci of this stream)
a61af66fc99e Initial load
duke
parents:
diff changeset
3891 scope_data()->set_stream(scope_data()->parent()->stream());
a61af66fc99e Initial load
duke
parents:
diff changeset
3892
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 // Pass parameters into callee state: add assignments
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 // note: this will also ensure that all arguments are computed before being passed
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 ValueStack* callee_state = state();
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3896 ValueStack* caller_state = state()->caller_state();
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3897 for (int i = args_base; i < caller_state->stack_size(); ) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3898 const int arg_no = i - args_base;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3899 Value arg = caller_state->stack_at_inc(i);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3900 store_local(callee_state, arg, arg_no);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3902
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 // Remove args from stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 // Note that we preserve locals state in case we can use it later
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 // (see use of pop_scope() below)
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 caller_state->truncate_stack(args_base);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3907 assert(callee_state->stack_size() == 0, "callee stack must be empty");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3908
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 Value lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
3910 BlockBegin* sync_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3911
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 // Inline the locking of the receiver if the callee is synchronized
a61af66fc99e Initial load
duke
parents:
diff changeset
3913 if (callee->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror())))
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 : state()->local_at(0);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
3916 sync_handler = new BlockBegin(SynchronizationEntryBCI);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 inline_sync_entry(lock, sync_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3919
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
3920 if (compilation()->env()->dtrace_method_probes()) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
3921 Values* args = new Values(1);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
3922 args->push(append(new Constant(new MethodConstant(method()))));
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2007
diff changeset
3923 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
3924 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3925
4116
973293defacd 7112085: assert(fr.interpreter_frame_expression_stack_size()==0) failed: only handle empty stacks
iveresov
parents: 3997
diff changeset
3926 if (profile_inlined_calls()) {
973293defacd 7112085: assert(fr.interpreter_frame_expression_stack_size()==0) failed: only handle empty stacks
iveresov
parents: 3997
diff changeset
3927 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
3928 }
973293defacd 7112085: assert(fr.interpreter_frame_expression_stack_size()==0) failed: only handle empty stacks
iveresov
parents: 3997
diff changeset
3929
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 BlockBegin* callee_start_block = block_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 if (callee_start_block != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header");
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 Goto* goto_callee = new Goto(callee_start_block, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 // The state for this goto is in the scope of the callee, so use
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 // the entry bci for the callee instead of the call site bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 append_with_bci(goto_callee, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 _block->set_end(goto_callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 callee_start_block->merge(callee_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
3939
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 _last = _block = callee_start_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
3941
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 scope_data()->add_to_work_list(callee_start_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3944
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 // Clear out bytecode stream
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 scope_data()->set_stream(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3947
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 // Ready to resume parsing in callee (either in the same block we
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 // were in before or in the callee's start block)
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 iterate_all_blocks(callee_start_block == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3951
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 // If we bailed out during parsing, return immediately (this is bad news)
7603
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3953 if (bailed_out())
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
3954 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3955
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 // iterate_all_blocks theoretically traverses in random order; in
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 // practice, we have only traversed the continuation if we are
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 // inlining into a subroutine
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 assert(continuation_existed ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 !continuation()->is_set(BlockBegin::was_visited_flag),
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 "continuation should not have been parsed yet if we created it");
a61af66fc99e Initial load
duke
parents:
diff changeset
3962
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 // At this point we are almost ready to return and resume parsing of
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 // the caller back in the GraphBuilder. The only thing we want to do
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 // first is an optimization: during parsing of the callee we
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 // generated at least one Goto to the continuation block. If we
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 // generated exactly one, and if the inlined method spanned exactly
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 // one block (and we didn't have to Goto its entry), then we snip
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 // off the Goto to the continuation, allowing control to fall
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 // through back into the caller block and effectively performing
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 // block merging. This allows load elimination and CSE to take place
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 // across multiple callee scopes if they are relatively simple, and
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 // is currently essential to making inlining profitable.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3974 if (num_returns() == 1
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3975 && block() == orig_block
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3976 && block() == inline_cleanup_block()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3977 _last = inline_cleanup_return_prev();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3978 _state = inline_cleanup_state();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3979 } else if (continuation_preds == cont->number_of_preds()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3980 // Inlining caused that the instructions after the invoke in the
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3981 // caller are not reachable any more. So skip filling this block
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3982 // with instructions!
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3983 assert(cont == continuation(), "");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3984 assert(_last && _last->as_BlockEnd(), "");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3985 _skip_block = true;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3986 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3987 // Resume parsing in continuation block unless it was already parsed.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3988 // Note that if we don't change _last here, iteration in
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3989 // iterate_bytecodes_for_block will stop when we return.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3990 if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3991 // add continuation to work list instead of parsing it immediately
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 assert(_last && _last->as_BlockEnd(), "");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
3993 scope_data()->parent()->add_to_work_list(continuation());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 _skip_block = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3997
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 // Fill the exception handler for synchronized methods with instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 if (callee->is_synchronized() && sync_handler->state() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 fill_sync_handler(lock, sync_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 pop_scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4004
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 compilation()->notice_inlined_method(callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
4006
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4009
a61af66fc99e Initial load
duke
parents:
diff changeset
4010
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6616
diff changeset
4011 bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4012 ValueStack* state_before = state()->copy_for_parsing();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4013 vmIntrinsics::ID iid = callee->intrinsic_id();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4014 switch (iid) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4015 case vmIntrinsics::_invokeBasic:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4016 {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4017 // get MethodHandle receiver
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4018 const int args_base = state()->stack_size() - callee->arg_size();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4019 ValueType* type = state()->stack_at(args_base)->type();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4020 if (type->is_constant()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4021 ciMethod* target = type->as_ObjectType()->constant_value()->as_method_handle()->get_vmtarget();
6892
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4022 // We don't do CHA here so only inline static and statically bindable methods.
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4023 if (target->is_static() || target->can_be_statically_bound()) {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4024 Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4025 if (try_inline(target, /*holder_known*/ true, bc)) {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4026 return true;
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4027 }
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4028 } else {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4029 print_inlining(target, "not static or statically bindable", /*success*/ false);
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4030 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4031 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4032 print_inlining(callee, "receiver not constant", /*success*/ false);
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4033 }
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4034 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4035 break;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4036
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4037 case vmIntrinsics::_linkToVirtual:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4038 case vmIntrinsics::_linkToStatic:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4039 case vmIntrinsics::_linkToSpecial:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4040 case vmIntrinsics::_linkToInterface:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4041 {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4042 // pop MemberName argument
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4043 const int args_base = state()->stack_size() - callee->arg_size();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4044 ValueType* type = apop()->type();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4045 if (type->is_constant()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4046 ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4047 // If the target is another method handle invoke try recursivly to get
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4048 // a better target.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4049 if (target->is_method_handle_intrinsic()) {
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6616
diff changeset
4050 if (try_method_handle_inline(target)) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4051 return true;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4052 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4053 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4054 ciSignature* signature = target->signature();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4055 const int receiver_skip = target->is_static() ? 0 : 1;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4056 // Cast receiver to its type.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4057 if (!target->is_static()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4058 ciKlass* tk = signature->accessing_klass();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4059 Value obj = state()->stack_at(args_base);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4060 if (obj->exact_type() == NULL &&
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4061 obj->declared_type() != tk && tk != compilation()->env()->Object_klass()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4062 TypeCast* c = new TypeCast(tk, obj, state_before);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4063 append(c);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4064 state()->stack_at_put(args_base, c);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4065 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4066 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4067 // Cast reference arguments to its type.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4068 for (int i = 0, j = 0; i < signature->count(); i++) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4069 ciType* t = signature->type_at(i);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4070 if (t->is_klass()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4071 ciKlass* tk = t->as_klass();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4072 Value obj = state()->stack_at(args_base + receiver_skip + j);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4073 if (obj->exact_type() == NULL &&
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4074 obj->declared_type() != tk && tk != compilation()->env()->Object_klass()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4075 TypeCast* c = new TypeCast(t, obj, state_before);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4076 append(c);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4077 state()->stack_at_put(args_base + receiver_skip + j, c);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4078 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4079 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4080 j += t->size(); // long and double take two slots
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4081 }
6892
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4082 // We don't do CHA here so only inline static and statically bindable methods.
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4083 if (target->is_static() || target->can_be_statically_bound()) {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4084 Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4085 if (try_inline(target, /*holder_known*/ true, bc)) {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4086 return true;
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4087 }
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4088 } else {
fd1d564dd460 8000821: JSR 292: C1 fails to call virtual method (JRUBY-6920)
twisti
parents: 6843
diff changeset
4089 print_inlining(target, "not static or statically bindable", /*success*/ false);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4090 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4091 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4092 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4093 print_inlining(callee, "MemberName not constant", /*success*/ false);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4094 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4095 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4096 break;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4097
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4098 default:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4099 fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4100 break;
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4101 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4102 set_state(state_before);
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4103 return false;
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4104 }
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4105
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3897
diff changeset
4106
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 void GraphBuilder::inline_bailout(const char* msg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 assert(msg != NULL, "inline bailout msg must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 _inline_bailout_msg = msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4111
a61af66fc99e Initial load
duke
parents:
diff changeset
4112
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 void GraphBuilder::clear_inline_bailout() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 _inline_bailout_msg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4116
a61af66fc99e Initial load
duke
parents:
diff changeset
4117
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 void GraphBuilder::push_root_scope(IRScope* scope, BlockList* bci2block, BlockBegin* start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 ScopeData* data = new ScopeData(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 data->set_scope(scope);
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 data->set_bci2block(bci2block);
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 _scope_data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 _block = start;
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4125
a61af66fc99e Initial load
duke
parents:
diff changeset
4126
a61af66fc99e Initial load
duke
parents:
diff changeset
4127 void GraphBuilder::push_scope(ciMethod* callee, BlockBegin* continuation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 IRScope* callee_scope = new IRScope(compilation(), scope(), bci(), callee, -1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 scope()->add_callee(callee_scope);
a61af66fc99e Initial load
duke
parents:
diff changeset
4130
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 BlockListBuilder blb(compilation(), callee_scope, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
4133
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 if (!blb.bci2block()->at(0)->is_set(BlockBegin::parser_loop_header_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4135 // this scope can be inlined directly into the caller so remove
a61af66fc99e Initial load
duke
parents:
diff changeset
4136 // the block at bci 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 blb.bci2block()->at_put(0, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4139
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
4140 set_state(new ValueStack(callee_scope, state()->copy(ValueStack::CallerState, bci())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4141
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 ScopeData* data = new ScopeData(scope_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
4143 data->set_scope(callee_scope);
a61af66fc99e Initial load
duke
parents:
diff changeset
4144 data->set_bci2block(blb.bci2block());
a61af66fc99e Initial load
duke
parents:
diff changeset
4145 data->set_continuation(continuation);
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 _scope_data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4148
a61af66fc99e Initial load
duke
parents:
diff changeset
4149
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 void GraphBuilder::push_scope_for_jsr(BlockBegin* jsr_continuation, int jsr_dest_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4151 ScopeData* data = new ScopeData(scope_data());
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 data->set_parsing_jsr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 data->set_jsr_entry_bci(jsr_dest_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
4154 data->set_jsr_return_address_local(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 // Must clone bci2block list as we will be mutating it in order to
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 // properly clone all blocks in jsr region as well as exception
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 // handlers containing rets
a61af66fc99e Initial load
duke
parents:
diff changeset
4158 BlockList* new_bci2block = new BlockList(bci2block()->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
4159 new_bci2block->push_all(bci2block());
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 data->set_bci2block(new_bci2block);
a61af66fc99e Initial load
duke
parents:
diff changeset
4161 data->set_scope(scope());
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 data->setup_jsr_xhandlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 data->set_continuation(continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 data->set_jsr_continuation(jsr_continuation);
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 _scope_data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4167
a61af66fc99e Initial load
duke
parents:
diff changeset
4168
a61af66fc99e Initial load
duke
parents:
diff changeset
4169 void GraphBuilder::pop_scope() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4170 int number_of_locks = scope()->number_of_locks();
a61af66fc99e Initial load
duke
parents:
diff changeset
4171 _scope_data = scope_data()->parent();
a61af66fc99e Initial load
duke
parents:
diff changeset
4172 // accumulate minimum number of monitor slots to be reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 scope()->set_min_number_of_locks(number_of_locks);
a61af66fc99e Initial load
duke
parents:
diff changeset
4174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4175
a61af66fc99e Initial load
duke
parents:
diff changeset
4176
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 void GraphBuilder::pop_scope_for_jsr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4178 _scope_data = scope_data()->parent();
a61af66fc99e Initial load
duke
parents:
diff changeset
4179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4180
a61af66fc99e Initial load
duke
parents:
diff changeset
4181 bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4183 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4184 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4185 Instruction* offset = args->at(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4186 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4187 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4188 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile));
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 push(op->type(), op);
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4193 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4195
a61af66fc99e Initial load
duke
parents:
diff changeset
4196
a61af66fc99e Initial load
duke
parents:
diff changeset
4197 bool GraphBuilder::append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4201 Instruction* offset = args->at(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4204 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4207 kill_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4211
a61af66fc99e Initial load
duke
parents:
diff changeset
4212
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 bool GraphBuilder::append_unsafe_get_raw(ciMethod* callee, BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4217 Instruction* op = append(new UnsafeGetRaw(t, args->at(1), false));
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 push(op->type(), op);
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4223
a61af66fc99e Initial load
duke
parents:
diff changeset
4224
a61af66fc99e Initial load
duke
parents:
diff changeset
4225 bool GraphBuilder::append_unsafe_put_raw(ciMethod* callee, BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 Instruction* op = append(new UnsafePutRaw(t, args->at(1), args->at(2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4234
a61af66fc99e Initial load
duke
parents:
diff changeset
4235
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 bool GraphBuilder::append_unsafe_prefetch(ciMethod* callee, bool is_static, bool is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 if (InlineUnsafeOps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 int obj_arg_index = 1; // Assume non-static case
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 if (is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 obj_arg_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4242 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 null_check(args->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4245 Instruction* offset = args->at(obj_arg_index + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4247 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4248 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset))
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4253 return InlineUnsafeOps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4255
a61af66fc99e Initial load
duke
parents:
diff changeset
4256
a61af66fc99e Initial load
duke
parents:
diff changeset
4257 void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
4258 ValueStack* state_before = copy_state_for_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4259 ValueType* result_type = as_ValueType(callee->return_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
4260 assert(result_type->is_int(), "int result");
a61af66fc99e Initial load
duke
parents:
diff changeset
4261 Values* args = state()->pop_arguments(callee->arg_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4262
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 // Pop off some args to speically handle, then push back
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 Value newval = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4265 Value cmpval = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4266 Value offset = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4267 Value src = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 Value unsafe_obj = args->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4269
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 // Separately handle the unsafe arg. It is not needed for code
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 // generation, but must be null checked
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 null_check(unsafe_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
4273
a61af66fc99e Initial load
duke
parents:
diff changeset
4274 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4276 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4277
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 args->push(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 args->push(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 args->push(cmpval);
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 args->push(newval);
a61af66fc99e Initial load
duke
parents:
diff changeset
4282
a61af66fc99e Initial load
duke
parents:
diff changeset
4283 // An unsafe CAS can alias with other field accesses, but we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
4284 // know which ones so mark the state as no preserved. This will
a61af66fc99e Initial load
duke
parents:
diff changeset
4285 // cause CSE to invalidate memory across it.
a61af66fc99e Initial load
duke
parents:
diff changeset
4286 bool preserves_state = false;
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1791
diff changeset
4287 Intrinsic* result = new Intrinsic(result_type, callee->intrinsic_id(), args, false, state_before, preserves_state);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4288 append_split(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
4289 push(result_type, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 compilation()->set_has_unsafe_access(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4292
a61af66fc99e Initial load
duke
parents:
diff changeset
4293
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4294 void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool success) {
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4295 CompileLog* log = compilation()->log();
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4296 if (log != NULL) {
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4297 if (success) {
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4298 if (msg != NULL)
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4299 log->inline_success(msg);
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4300 else
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4301 log->inline_success("receiver is statically known");
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4302 } else {
7603
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
4303 if (msg != NULL)
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
4304 log->inline_fail(msg);
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
4305 else
d92fa52a5d03 8006095: C1: SIGSEGV w/ -XX:+LogCompilation
vlivanov
parents: 7425
diff changeset
4306 log->inline_fail("reason unknown");
6843
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4307 }
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4308 }
c3e799c37717 7177003: C1: LogCompilation support
vlivanov
parents: 6795
diff changeset
4309
12295
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12165
diff changeset
4310 if (!PrintInlining && !compilation()->method()->has_option("PrintInlining")) {
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12165
diff changeset
4311 return;
1b64d46620a3 8022585: VM crashes when ran with -XX:+PrintInlining
kvn
parents: 12165
diff changeset
4312 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4313 CompileTask::print_inlining(callee, scope()->level(), bci(), msg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4314 if (success && CIPrintMethodCodes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4315 callee->print_codes();
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4318
6795
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4319 bool GraphBuilder::append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4320 if (InlineUnsafeOps) {
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4321 Values* args = state()->pop_arguments(callee->arg_size());
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4322 BasicType t = callee->return_type()->basic_type();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4323 null_check(args->at(0));
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4324 Instruction* offset = args->at(2);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4325 #ifndef _LP64
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4326 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4327 #endif
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4328 Instruction* op = append(new UnsafeGetAndSetObject(t, args->at(1), offset, args->at(3), is_add));
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4329 compilation()->set_has_unsafe_access(true);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4330 kill_all();
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4331 push(op->type(), op);
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4332 }
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4333 return InlineUnsafeOps;
7eca5de9e0b6 7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents: 6725
diff changeset
4334 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4335
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6222
diff changeset
4336 #ifndef PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4337 void GraphBuilder::print_stats() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4338 vmap()->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
4341
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
4342 void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) {
13165
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4343 assert(known_holder == NULL || (known_holder->is_instance_klass() &&
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4344 (!known_holder->is_interface() ||
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4345 ((ciInstanceKlass*)known_holder)->has_default_methods())), "should be default method");
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4346 if (known_holder != NULL) {
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4347 if (known_holder->exact_klass() == NULL) {
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4348 known_holder = compilation()->cha_exact_type(known_holder);
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4349 }
13075
144b23411b51 8027632: assert(xtype->klass_is_exact()) failed: Should be exact at graphKit.cpp
roland
parents: 13021
diff changeset
4350 }
13165
0097301f34fa integrated patch from Roland that prevents abstract types showing up in C1 generated type profiles
Doug Simon <doug.simon@oracle.com>
parents: 13086
diff changeset
4351
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12295
diff changeset
4352 append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4354
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4355 void GraphBuilder::profile_return_type(Value ret, ciMethod* callee, ciMethod* m, int invoke_bci) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4356 assert((m == NULL) == (invoke_bci < 0), "invalid method and invalid bci together");
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4357 if (m == NULL) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4358 m = method();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4359 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4360 if (invoke_bci < 0) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4361 invoke_bci = bci();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4362 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4363 ciMethodData* md = m->method_data_or_null();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4364 ciProfileData* data = md->bci_to_data(invoke_bci);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4365 if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4366 append(new ProfileReturnType(m , invoke_bci, callee, ret));
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4367 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4368 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
4369
1825
80c9354976b0 6988346: 6986046 breaks tiered
iveresov
parents: 1819
diff changeset
4370 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) {
80c9354976b0 6988346: 6986046 breaks tiered
iveresov
parents: 1819
diff changeset
4371 append(new ProfileInvoke(callee, state));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 }