annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 20543:e7d0505c8a30

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