annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 6862:8a5ea0a9ccc4

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