annotate src/share/vm/opto/parse1.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents 194b8e3a2fc4
children 98cb887364d3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 164
diff changeset
2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_parse1.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // Static array so we can figure out which bytecodes stop us from compiling
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // the most. Some of the non-static variables are needed in bytecodeInfo.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // and eventually should be encapsulated in a proper class (gri 8/18/98).
a61af66fc99e Initial load
duke
parents:
diff changeset
31
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
32 int nodes_created = 0;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
33 int methods_parsed = 0;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
34 int methods_seen = 0;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
35 int blocks_parsed = 0;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
36 int blocks_seen = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
38 int explicit_null_checks_inserted = 0;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
39 int explicit_null_checks_elided = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
40 int all_null_checks_found = 0, implicit_null_checks = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 int implicit_null_throws = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 int reclaim_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 int reclaim_in = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 int reclaim_node = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
48 bool Parse::BytecodeParseHistogram::_initialized = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 uint Parse::BytecodeParseHistogram::_bytecodes_parsed [Bytecodes::number_of_codes];
a61af66fc99e Initial load
duke
parents:
diff changeset
50 uint Parse::BytecodeParseHistogram::_nodes_constructed[Bytecodes::number_of_codes];
a61af66fc99e Initial load
duke
parents:
diff changeset
51 uint Parse::BytecodeParseHistogram::_nodes_transformed[Bytecodes::number_of_codes];
a61af66fc99e Initial load
duke
parents:
diff changeset
52 uint Parse::BytecodeParseHistogram::_new_values [Bytecodes::number_of_codes];
a61af66fc99e Initial load
duke
parents:
diff changeset
53 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 //------------------------------print_statistics-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
56 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
57 void Parse::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 tty->print_cr("--- Compiler Statistics ---");
a61af66fc99e Initial load
duke
parents:
diff changeset
59 tty->print("Methods seen: %d Methods parsed: %d", methods_seen, methods_parsed);
a61af66fc99e Initial load
duke
parents:
diff changeset
60 tty->print(" Nodes created: %d", nodes_created);
a61af66fc99e Initial load
duke
parents:
diff changeset
61 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
62 if (methods_seen != methods_parsed)
a61af66fc99e Initial load
duke
parents:
diff changeset
63 tty->print_cr("Reasons for parse failures (NOT cumulative):");
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
64 tty->print_cr("Blocks parsed: %d Blocks seen: %d", blocks_parsed, blocks_seen);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if( explicit_null_checks_inserted )
a61af66fc99e Initial load
duke
parents:
diff changeset
67 tty->print_cr("%d original NULL checks - %d elided (%2d%%); optimizer leaves %d,", explicit_null_checks_inserted, explicit_null_checks_elided, (100*explicit_null_checks_elided)/explicit_null_checks_inserted, all_null_checks_found);
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if( all_null_checks_found )
a61af66fc99e Initial load
duke
parents:
diff changeset
69 tty->print_cr("%d made implicit (%2d%%)", implicit_null_checks,
a61af66fc99e Initial load
duke
parents:
diff changeset
70 (100*implicit_null_checks)/all_null_checks_found);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 if( implicit_null_throws )
a61af66fc99e Initial load
duke
parents:
diff changeset
72 tty->print_cr("%d implicit null exceptions at runtime",
a61af66fc99e Initial load
duke
parents:
diff changeset
73 implicit_null_throws);
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if( PrintParseStatistics && BytecodeParseHistogram::initialized() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 BytecodeParseHistogram::print();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 //------------------------------ON STACK REPLACEMENT---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // Construct a node which can be used to get incoming state for
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // on stack replacement.
a61af66fc99e Initial load
duke
parents:
diff changeset
85 Node *Parse::fetch_interpreter_state(int index,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 Node *local_addrs,
a61af66fc99e Initial load
duke
parents:
diff changeset
88 Node *local_addrs_base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 Node *mem = memory(Compile::AliasIdxRaw);
a61af66fc99e Initial load
duke
parents:
diff changeset
90 Node *adr = basic_plus_adr( local_addrs_base, local_addrs, -index*wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Very similar to LoadNode::make, except we handle un-aligned longs and
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // doubles on Sparc. Intel can handle them just fine directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 Node *l;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 switch( bt ) { // Signature is flattened
a61af66fc99e Initial load
duke
parents:
diff changeset
96 case T_INT: l = new (C, 3) LoadINode( 0, mem, adr, TypeRawPtr::BOTTOM ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 case T_FLOAT: l = new (C, 3) LoadFNode( 0, mem, adr, TypeRawPtr::BOTTOM ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 case T_ADDRESS:
a61af66fc99e Initial load
duke
parents:
diff changeset
99 case T_OBJECT: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
101 case T_DOUBLE: {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Since arguments are in reverse order, the argument address 'adr'
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // refers to the back half of the long/double. Recompute adr.
a61af66fc99e Initial load
duke
parents:
diff changeset
104 adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
105 if( Matcher::misaligned_doubles_ok ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 l = (bt == T_DOUBLE)
a61af66fc99e Initial load
duke
parents:
diff changeset
107 ? (Node*)new (C, 3) LoadDNode( 0, mem, adr, TypeRawPtr::BOTTOM )
a61af66fc99e Initial load
duke
parents:
diff changeset
108 : (Node*)new (C, 3) LoadLNode( 0, mem, adr, TypeRawPtr::BOTTOM );
a61af66fc99e Initial load
duke
parents:
diff changeset
109 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 l = (bt == T_DOUBLE)
a61af66fc99e Initial load
duke
parents:
diff changeset
111 ? (Node*)new (C, 3) LoadD_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM )
a61af66fc99e Initial load
duke
parents:
diff changeset
112 : (Node*)new (C, 3) LoadL_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM );
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return _gvn.transform(l);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Helper routine to prevent the interpreter from handing
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // unexpected typestate to an OSR method.
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // The Node l is a value newly dug out of the interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // The type is the type predicted by ciTypeFlow. Note that it is
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // not a general type, but can only come from Type::get_typeflow_type.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // The safepoint is a map which will feed an uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 Node* Parse::check_interpreter_type(Node* l, const Type* type,
a61af66fc99e Initial load
duke
parents:
diff changeset
128 SafePointNode* &bad_type_exit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 const TypeOopPtr* tp = type->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // TypeFlow may assert null-ness if a type appears unloaded.
a61af66fc99e Initial load
duke
parents:
diff changeset
133 if (type == TypePtr::NULL_PTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
134 (tp != NULL && !tp->klass()->is_loaded())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Value must be null, not a real oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
136 Node* chk = _gvn.transform( new (C, 3) CmpPNode(l, null()) );
a61af66fc99e Initial load
duke
parents:
diff changeset
137 Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, BoolTest::eq) );
a61af66fc99e Initial load
duke
parents:
diff changeset
138 IfNode* iff = create_and_map_if(control(), tst, PROB_MAX, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 set_control(_gvn.transform( new (C, 1) IfTrueNode(iff) ));
a61af66fc99e Initial load
duke
parents:
diff changeset
140 Node* bad_type = _gvn.transform( new (C, 1) IfFalseNode(iff) );
a61af66fc99e Initial load
duke
parents:
diff changeset
141 bad_type_exit->control()->add_req(bad_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
142 l = null();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Typeflow can also cut off paths from the CFG, based on
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // types which appear unloaded, or call sites which appear unlinked.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // When paths are cut off, values at later merge points can rise
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // toward more specific classes. Make sure these specific classes
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // are still in effect.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (tp != NULL && tp->klass() != C->env()->Object_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // TypeFlow asserted a specific object type. Value must have that type.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 Node* bad_type_ctrl = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 l = gen_checkcast(l, makecon(TypeKlassPtr::make(tp->klass())), &bad_type_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 bad_type_exit->control()->add_req(bad_type_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 BasicType bt_l = _gvn.type(l)->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
158 BasicType bt_t = type->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
159 assert(_gvn.type(l)->higher_equal(type), "must constrain OSR typestate");
a61af66fc99e Initial load
duke
parents:
diff changeset
160 return l;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Helper routine which sets up elements of the initial parser map when
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // performing a parse for on stack replacement. Add values into map.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // The only parameter contains the address of a interpreter arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 void Parse::load_interpreter_state(Node* osr_buf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 int max_locals = jvms()->loc_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
169 int max_stack = jvms()->stk_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Mismatch between method and jvms can occur since map briefly held
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // an OSR entry state (which takes up one RawPtr word).
a61af66fc99e Initial load
duke
parents:
diff changeset
174 assert(max_locals == method()->max_locals(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
175 assert(max_stack >= method()->max_stack(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
176 assert((int)jvms()->endoff() == TypeFunc::Parms + max_locals + max_stack, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
177 assert((int)jvms()->endoff() == (int)map()->req(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Find the start block.
a61af66fc99e Initial load
duke
parents:
diff changeset
180 Block* osr_block = start_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 assert(osr_block->start() == osr_bci(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Set initial BCI.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 set_parse_bci(osr_block->start());
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Set initial stack depth.
a61af66fc99e Initial load
duke
parents:
diff changeset
187 set_sp(osr_block->start_sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Check bailouts. We currently do not perform on stack replacement
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // of loops in catch blocks or loops which branch with a non-empty stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (sp() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 C->record_method_not_compilable("OSR starts with non-empty stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
193 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Do not OSR inside finally clauses:
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if (osr_block->has_trap_at(osr_block->start())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 C->record_method_not_compilable("OSR starts with an immediate trap");
a61af66fc99e Initial load
duke
parents:
diff changeset
198 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // Commute monitors from interpreter frame to compiler frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
202 assert(jvms()->monitor_depth() == 0, "should be no active locks at beginning of osr");
a61af66fc99e Initial load
duke
parents:
diff changeset
203 int mcnt = osr_block->flow()->monitor_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
204 Node *monitors_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals+mcnt*2-1)*wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 for (index = 0; index < mcnt; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // Make a BoxLockNode for the monitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
207 Node *box = _gvn.transform(new (C, 1) BoxLockNode(next_monitor()));
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // Displaced headers and locked objects are interleaved in the
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // temp OSR buffer. We only copy the locked objects out here.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // Fetch the locked object from the OSR temp buffer and copy to our fastlock node.
a61af66fc99e Initial load
duke
parents:
diff changeset
213 Node *lock_object = fetch_interpreter_state(index*2, T_OBJECT, monitors_addr, osr_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Try and copy the displaced header to the BoxNode
a61af66fc99e Initial load
duke
parents:
diff changeset
215 Node *displaced_hdr = fetch_interpreter_state((index*2) + 1, T_ADDRESS, monitors_addr, osr_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 store_to_memory(control(), box, displaced_hdr, T_ADDRESS, Compile::AliasIdxRaw);
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // Build a bogus FastLockNode (no code will be generated) and push the
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // monitor into our debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
222 const FastLockNode *flock = _gvn.transform(new (C, 3) FastLockNode( 0, lock_object, box ))->as_FastLock();
a61af66fc99e Initial load
duke
parents:
diff changeset
223 map()->push_monitor(flock);
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // If the lock is our method synchronization lock, tuck it away in
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // _sync_lock for return and rethrow exit paths.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if (index == 0 && method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _synch_lock = flock;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 MethodLivenessResult live_locals = method()->liveness_at_bci(osr_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (!live_locals.is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Degenerate or breakpointed method.
a61af66fc99e Initial load
duke
parents:
diff changeset
235 C->record_method_not_compilable("OSR in empty or breakpointed method");
a61af66fc99e Initial load
duke
parents:
diff changeset
236 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // Extract the needed locals from the interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
240 Node *locals_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals-1)*wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // find all the locals that the interpreter thinks contain live oops
a61af66fc99e Initial load
duke
parents:
diff changeset
243 const BitMap live_oops = method()->live_local_oops_at_bci(osr_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
244 for (index = 0; index < max_locals; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 if (!live_locals.at(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 const Type *type = osr_block->local_type_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (type->isa_oopptr() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // 6403625: Verify that the interpreter oopMap thinks that the oop is live
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // else we might load a stale oop if the MethodLiveness disagrees with the
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // result of the interpreter. If the interpreter says it is dead we agree
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // by making the value go to top.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 //
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (!live_oops.at(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 if (C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 C->log()->elem("OSR_mismatch local_index='%d'",index);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 set_local(index, null());
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // and ignore it for the loads
a61af66fc99e Initial load
duke
parents:
diff changeset
266 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Filter out TOP, HALF, and BOTTOM. (Cf. ensure_phi.)
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (type == Type::TOP || type == Type::HALF) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // If the type falls to bottom, then this must be a local that
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // is mixing ints and oops or some such. Forcing it to top
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // makes it go dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
277 if (type == Type::BOTTOM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Construct code to access the appropriate local.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 Node *value = fetch_interpreter_state(index, type->basic_type(), locals_addr, osr_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 set_local(index, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Extract the needed stack entries from the interpreter frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 for (index = 0; index < sp(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 const Type *type = osr_block->stack_type_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if (type != Type::TOP) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // Currently the compiler bails out when attempting to on stack replace
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // at a bci with a non-empty stack. We should not reach here.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // End the OSR migration
a61af66fc99e Initial load
duke
parents:
diff changeset
296 make_runtime_call(RC_LEAF, OptoRuntime::osr_end_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
297 CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_end),
a61af66fc99e Initial load
duke
parents:
diff changeset
298 "OSR_migration_end", TypeRawPtr::BOTTOM,
a61af66fc99e Initial load
duke
parents:
diff changeset
299 osr_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // Now that the interpreter state is loaded, make sure it will match
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // at execution time what the compiler is expecting now:
a61af66fc99e Initial load
duke
parents:
diff changeset
303 SafePointNode* bad_type_exit = clone_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
304 bad_type_exit->set_control(new (C, 1) RegionNode(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 for (index = 0; index < max_locals; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 if (stopped()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 Node* l = local(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (l->is_top()) continue; // nothing here
a61af66fc99e Initial load
duke
parents:
diff changeset
310 const Type *type = osr_block->local_type_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (type->isa_oopptr() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (!live_oops.at(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // skip type check for dead oops
a61af66fc99e Initial load
duke
parents:
diff changeset
314 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 set_local(index, check_interpreter_type(l, type, bad_type_exit));
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 for (index = 0; index < sp(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if (stopped()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
322 Node* l = stack(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if (l->is_top()) continue; // nothing here
a61af66fc99e Initial load
duke
parents:
diff changeset
324 const Type *type = osr_block->stack_type_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
325 set_stack(index, check_interpreter_type(l, type, bad_type_exit));
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (bad_type_exit->control()->req() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // Build an uncommon trap here, if any inputs can be unexpected.
a61af66fc99e Initial load
duke
parents:
diff changeset
330 bad_type_exit->set_control(_gvn.transform( bad_type_exit->control() ));
a61af66fc99e Initial load
duke
parents:
diff changeset
331 record_for_igvn(bad_type_exit->control());
a61af66fc99e Initial load
duke
parents:
diff changeset
332 SafePointNode* types_are_good = map();
a61af66fc99e Initial load
duke
parents:
diff changeset
333 set_map(bad_type_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // The unexpected type happens because a new edge is active
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // in the CFG, which typeflow had previously ignored.
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // E.g., Object x = coldAtFirst() && notReached()? "str": new Integer(123).
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // This x will be typed as Integer if notReached is not yet linked.
a61af66fc99e Initial load
duke
parents:
diff changeset
338 uncommon_trap(Deoptimization::Reason_unreached,
a61af66fc99e Initial load
duke
parents:
diff changeset
339 Deoptimization::Action_reinterpret);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 set_map(types_are_good);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 //------------------------------Parse------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // Main parser constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
346 Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
a61af66fc99e Initial load
duke
parents:
diff changeset
347 : _exits(caller)
a61af66fc99e Initial load
duke
parents:
diff changeset
348 {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Init some variables
a61af66fc99e Initial load
duke
parents:
diff changeset
350 _caller = caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 _method = parse_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 _expected_uses = expected_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 _depth = 1 + (caller->has_method() ? caller->depth() : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 _wrote_final = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 _entry_bci = InvocationEntryBci;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 _tf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 _block = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
358 debug_only(_block_count = -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 debug_only(_blocks = (Block*)-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
361 if (PrintCompilation || PrintOpto) {
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Make sure I have an inline tree, so I can print messages about it.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 JVMState* ilt_caller = is_osr_parse() ? caller->caller() : caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 InlineTree::find_subtree_from_root(C->ilt(), ilt_caller, parse_method, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 _max_switch_depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 _est_switch_depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 _tf = TypeFunc::make(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
371 _iter.reset_to_method(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
372 _flow = method()->get_flow_analysis();
a61af66fc99e Initial load
duke
parents:
diff changeset
373 if (_flow->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 C->record_method_not_compilable_all_tiers(_flow->failure_reason());
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
377 #ifndef PRODUCT
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
378 if (_flow->has_irreducible_entry()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
379 C->set_parsed_irreducible_loop(true);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
380 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
381 #endif
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
382
0
a61af66fc99e Initial load
duke
parents:
diff changeset
383 if (_expected_uses <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
384 _prof_factor = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
386 float prof_total = parse_method->interpreter_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
387 if (prof_total <= _expected_uses) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 _prof_factor = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 _prof_factor = _expected_uses / prof_total;
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393
a61af66fc99e Initial load
duke
parents:
diff changeset
394 CompileLog* log = C->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
396 log->begin_head("parse method='%d' uses='%g'",
a61af66fc99e Initial load
duke
parents:
diff changeset
397 log->identify(parse_method), expected_uses);
a61af66fc99e Initial load
duke
parents:
diff changeset
398 if (depth() == 1 && C->is_osr_compilation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 log->print(" osr_bci='%d'", C->entry_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 log->stamp();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 log->end_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Accumulate deoptimization counts.
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // (The range_check and store_check counts are checked elsewhere.)
a61af66fc99e Initial load
duke
parents:
diff changeset
407 ciMethodData* md = method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
408 for (uint reason = 0; reason < md->trap_reason_limit(); reason++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 uint md_count = md->trap_count(reason);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 if (md_count != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 if (md_count == md->trap_count_limit())
a61af66fc99e Initial load
duke
parents:
diff changeset
412 md_count += md->overflow_trap_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
413 uint total_count = C->trap_count(reason);
a61af66fc99e Initial load
duke
parents:
diff changeset
414 uint old_count = total_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
415 total_count += md_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // Saturate the add if it overflows.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 if (total_count < old_count || total_count < md_count)
a61af66fc99e Initial load
duke
parents:
diff changeset
418 total_count = (uint)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
419 C->set_trap_count(reason, total_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (log != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
421 log->elem("observe trap='%s' count='%d' total='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
422 Deoptimization::trap_reason_name(reason),
a61af66fc99e Initial load
duke
parents:
diff changeset
423 md_count, total_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // Accumulate total sum of decompilations, also.
a61af66fc99e Initial load
duke
parents:
diff changeset
427 C->set_decompile_count(C->decompile_count() + md->decompile_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 _count_invocations = C->do_count_invocations();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 _method_data_update = C->do_method_data_update();
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 if (log != NULL && method()->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 log->elem("observe that='has_exception_handlers'");
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 assert(method()->can_be_compiled(), "Can not parse this method, cutout earlier");
a61af66fc99e Initial load
duke
parents:
diff changeset
437 assert(method()->has_balanced_monitors(), "Can not parse unbalanced monitors, cutout earlier");
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Always register dependence if JVMTI is enabled, because
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // either breakpoint setting or hotswapping of methods may
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // cause deoptimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 C->dependencies()->assert_evol_method(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446 methods_seen++;
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Do some special top-level things.
a61af66fc99e Initial load
duke
parents:
diff changeset
449 if (depth() == 1 && C->is_osr_compilation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 _entry_bci = C->entry_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
451 _flow = method()->get_osr_flow_analysis(osr_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
452 if (_flow->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 C->record_method_not_compilable(_flow->failure_reason());
a61af66fc99e Initial load
duke
parents:
diff changeset
454 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
455 if (PrintOpto && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 tty->print_cr("OSR @%d type flow bailout: %s", _entry_bci, _flow->failure_reason());
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 method()->print_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
459 method()->print_codes();
a61af66fc99e Initial load
duke
parents:
diff changeset
460 _flow->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465 _tf = C->tf(); // the OSR entry type is different
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
469 if (depth() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 assert(C->is_osr_compilation() == this->is_osr_parse(), "OSR in sync");
a61af66fc99e Initial load
duke
parents:
diff changeset
471 if (C->tf() != tf()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 assert(C->env()->system_dictionary_modification_counter_changed(),
a61af66fc99e Initial load
duke
parents:
diff changeset
474 "Must invalidate if TypeFuncs differ");
a61af66fc99e Initial load
duke
parents:
diff changeset
475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
476 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 assert(!this->is_osr_parse(), "no recursive OSR");
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 methods_parsed++;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // add method size here to guarantee that inlined methods are added too
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (TimeCompiler)
a61af66fc99e Initial load
duke
parents:
diff changeset
485 _total_bytes_compiled += method()->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 show_parse_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
488 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 if (log) log->done("parse");
a61af66fc99e Initial load
duke
parents:
diff changeset
492 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 gvn().set_type(root(), root()->bottom_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
496 gvn().transform(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // Import the results of the ciTypeFlow.
a61af66fc99e Initial load
duke
parents:
diff changeset
499 init_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // Merge point for all normal exits
a61af66fc99e Initial load
duke
parents:
diff changeset
502 build_exits();
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Setup the initial JVM state map.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 SafePointNode* entry_map = create_entry_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // Check for bailouts during map initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if (failing() || entry_map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if (log) log->done("parse");
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 Node_Notes* caller_nn = C->default_node_notes();
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // Collect debug info for inlined calls unless -XX:-DebugInlinedCalls.
a61af66fc99e Initial load
duke
parents:
diff changeset
515 if (DebugInlinedCalls || depth() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 C->set_default_node_notes(make_node_notes(caller_nn));
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 if (is_osr_parse()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 Node* osr_buf = entry_map->in(TypeFunc::Parms+0);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 entry_map->set_req(TypeFunc::Parms+0, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
522 set_map(entry_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 load_interpreter_state(osr_buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
524 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 set_map(entry_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 do_method_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // Check for bailouts during method entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (log) log->done("parse");
a61af66fc99e Initial load
duke
parents:
diff changeset
532 C->set_default_node_notes(caller_nn);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 entry_map = map(); // capture any changes performed by method setup code
a61af66fc99e Initial load
duke
parents:
diff changeset
537 assert(jvms()->endoff() == map()->req(), "map matches JVMS layout");
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // We begin parsing as if we have just encountered a jump to the
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // method entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Block* entry_block = start_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
542 assert(entry_block->start() == (is_osr_parse() ? osr_bci() : 0), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
543 set_map_clone(entry_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
544 merge_common(entry_block, entry_block->next_path_num());
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
547 BytecodeParseHistogram *parse_histogram_obj = new (C->env()->arena()) BytecodeParseHistogram(this, C);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 set_parse_histogram( parse_histogram_obj );
a61af66fc99e Initial load
duke
parents:
diff changeset
549 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // Parse all the basic blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
552 do_all_blocks();
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 C->set_default_node_notes(caller_nn);
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Check for bailouts during conversion to graph
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 if (log) log->done("parse");
a61af66fc99e Initial load
duke
parents:
diff changeset
559 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // Fix up all exiting control flow.
a61af66fc99e Initial load
duke
parents:
diff changeset
563 set_map(entry_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 do_exits();
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 if (log) log->done("parse nodes='%d' memory='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
567 C->unique(), C->node_arena()->used());
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 //---------------------------do_all_blocks-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
571 void Parse::do_all_blocks() {
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
572 bool has_irreducible = flow()->has_irreducible_entry();
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
573
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
574 // Walk over all blocks in Reverse Post-Order.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
575 while (true) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
576 bool progress = false;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
577 for (int rpo = 0; rpo < block_count(); rpo++) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
578 Block* block = rpo_at(rpo);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
579
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
580 if (block->is_parsed()) continue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
581
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
582 if (!block->is_merged()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
583 // Dead block, no state reaches this block
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
584 continue;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
585 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
586
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
587 // Prepare to parse this block.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
588 load_state_from(block);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
589
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
590 if (stopped()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
591 // Block is dead.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
592 continue;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
593 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
594
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
595 blocks_parsed++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
596
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
597 progress = true;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
598 if (block->is_loop_head() || block->is_handler() || has_irreducible && !block->is_ready()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
599 // Not all preds have been parsed. We must build phis everywhere.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
600 // (Note that dead locals do not get phis built, ever.)
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
601 ensure_phis_everywhere();
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
602
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
603 // Leave behind an undisturbed copy of the map, for future merges.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
604 set_map(clone_map());
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
605 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
606
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
607 if (control()->is_Region() && !block->is_loop_head() && !has_irreducible && !block->is_handler()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
608 // In the absence of irreducible loops, the Region and Phis
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
609 // associated with a merge that doesn't involve a backedge can
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
610 // be simplfied now since the RPO parsing order guarantees
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
611 // that any path which was supposed to reach here has already
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
612 // been parsed or must be dead.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
613 Node* c = control();
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
614 Node* result = _gvn.transform_no_reclaim(control());
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
615 if (c != result && TraceOptoParse) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
616 tty->print_cr("Block #%d replace %d with %d", block->rpo(), c->_idx, result->_idx);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
617 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
618 if (result != top()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
619 record_for_igvn(result);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
620 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
621 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
622
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
623 // Parse the block.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
624 do_one_block();
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
625
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
626 // Check for bailouts.
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
627 if (failing()) return;
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
628 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
629
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
630 // with irreducible loops multiple passes might be necessary to parse everything
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
631 if (!has_irreducible || !progress) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
632 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
634 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
635
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
636 blocks_seen += block_count();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // Make sure there are no half-processed blocks remaining.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // Every remaining unprocessed block is dead and may be ignored now.
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
641 for (int rpo = 0; rpo < block_count(); rpo++) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
642 Block* block = rpo_at(rpo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
643 if (!block->is_parsed()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 if (TraceOptoParse) {
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
645 tty->print_cr("Skipped dead block %d at bci:%d", rpo, block->start());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
647 assert(!block->is_merged(), "no half-processed blocks");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
652
a61af66fc99e Initial load
duke
parents:
diff changeset
653 //-------------------------------build_exits----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Build normal and exceptional exit merge points.
a61af66fc99e Initial load
duke
parents:
diff changeset
655 void Parse::build_exits() {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // make a clone of caller to prevent sharing of side-effects
a61af66fc99e Initial load
duke
parents:
diff changeset
657 _exits.set_map(_exits.clone_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
658 _exits.clean_stack(_exits.sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
659 _exits.sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 RegionNode* region = new (C, 1) RegionNode(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
663 gvn().set_type_bottom(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 _exits.set_control(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // Note: iophi and memphi are not transformed until do_exits.
a61af66fc99e Initial load
duke
parents:
diff changeset
667 Node* iophi = new (C, region->req()) PhiNode(region, Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
668 Node* memphi = new (C, region->req()) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
669 _exits.set_i_o(iophi);
a61af66fc99e Initial load
duke
parents:
diff changeset
670 _exits.set_all_memory(memphi);
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // Add a return value to the exit state. (Do not push it yet.)
a61af66fc99e Initial load
duke
parents:
diff changeset
673 if (tf()->range()->cnt() > TypeFunc::Parms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
674 const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // Don't "bind" an unloaded return klass to the ret_phi. If the klass
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // becomes loaded during the subsequent parsing, the loaded and unloaded
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // types will not join when we transform and push in do_exits().
a61af66fc99e Initial load
duke
parents:
diff changeset
678 const TypeOopPtr* ret_oop_type = ret_type->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
679 if (ret_oop_type && !ret_oop_type->klass()->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 ret_type = TypeOopPtr::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
682 int ret_size = type2size[ret_type->basic_type()];
a61af66fc99e Initial load
duke
parents:
diff changeset
683 Node* ret_phi = new (C, region->req()) PhiNode(region, ret_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
684 _exits.ensure_stack(ret_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 assert((int)(tf()->range()->cnt() - TypeFunc::Parms) == ret_size, "good tf range");
a61af66fc99e Initial load
duke
parents:
diff changeset
686 assert(method()->return_type()->size() == ret_size, "tf agrees w/ method");
a61af66fc99e Initial load
duke
parents:
diff changeset
687 _exits.set_argument(0, ret_phi); // here is where the parser finds it
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // Note: ret_phi is not yet pushed, until do_exits.
a61af66fc99e Initial load
duke
parents:
diff changeset
689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
690 }
a61af66fc99e Initial load
duke
parents:
diff changeset
691
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 //----------------------------build_start_state-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // Construct a state which contains only the incoming arguments from an
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // unknown caller. The method & bci will be NULL & InvocationEntryBci.
a61af66fc99e Initial load
duke
parents:
diff changeset
696 JVMState* Compile::build_start_state(StartNode* start, const TypeFunc* tf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 int arg_size = tf->domain()->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
698 int max_size = MAX2(arg_size, (int)tf->range()->cnt());
a61af66fc99e Initial load
duke
parents:
diff changeset
699 JVMState* jvms = new (this) JVMState(max_size - TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
700 SafePointNode* map = new (this, max_size) SafePointNode(max_size, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
701 record_for_igvn(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 assert(arg_size == TypeFunc::Parms + (is_osr_compilation() ? 1 : method()->arg_size()), "correct arg_size");
a61af66fc99e Initial load
duke
parents:
diff changeset
703 Node_Notes* old_nn = default_node_notes();
a61af66fc99e Initial load
duke
parents:
diff changeset
704 if (old_nn != NULL && has_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 Node_Notes* entry_nn = old_nn->clone(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
706 JVMState* entry_jvms = new(this) JVMState(method(), old_nn->jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
707 entry_jvms->set_offsets(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
708 entry_jvms->set_bci(entry_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
709 entry_nn->set_jvms(entry_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 set_default_node_notes(entry_nn);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
712 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 for (i = 0; i < (uint)arg_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
714 Node* parm = initial_gvn()->transform(new (this, 1) ParmNode(start, i));
a61af66fc99e Initial load
duke
parents:
diff changeset
715 map->init_req(i, parm);
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // Record all these guys for later GVN.
a61af66fc99e Initial load
duke
parents:
diff changeset
717 record_for_igvn(parm);
a61af66fc99e Initial load
duke
parents:
diff changeset
718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
719 for (; i < map->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 map->init_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
722 assert(jvms->argoff() == TypeFunc::Parms, "parser gets arguments here");
a61af66fc99e Initial load
duke
parents:
diff changeset
723 set_default_node_notes(old_nn);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 map->set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 jvms->set_map(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
726 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 //-----------------------------make_node_notes---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
730 Node_Notes* Parse::make_node_notes(Node_Notes* caller_nn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 if (caller_nn == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 Node_Notes* nn = caller_nn->clone(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 JVMState* caller_jvms = nn->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
734 JVMState* jvms = new (C) JVMState(method(), caller_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
735 jvms->set_offsets(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 jvms->set_bci(_entry_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 nn->set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
738 return nn;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741
a61af66fc99e Initial load
duke
parents:
diff changeset
742 //--------------------------return_values--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
743 void Compile::return_values(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
745 Node* ret = new (this, TypeFunc::Parms) ReturnNode(TypeFunc::Parms,
a61af66fc99e Initial load
duke
parents:
diff changeset
746 kit.control(),
a61af66fc99e Initial load
duke
parents:
diff changeset
747 kit.i_o(),
a61af66fc99e Initial load
duke
parents:
diff changeset
748 kit.reset_memory(),
a61af66fc99e Initial load
duke
parents:
diff changeset
749 kit.frameptr(),
a61af66fc99e Initial load
duke
parents:
diff changeset
750 kit.returnadr());
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // Add zero or 1 return values
a61af66fc99e Initial load
duke
parents:
diff changeset
752 int ret_size = tf()->range()->cnt() - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 if (ret_size > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 kit.inc_sp(-ret_size); // pop the return value(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
755 kit.sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
756 ret->add_req(kit.argument(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // Note: The second dummy edge is not needed by a ReturnNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // bind it to root
a61af66fc99e Initial load
duke
parents:
diff changeset
760 root()->add_req(ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 record_for_igvn(ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 initial_gvn()->transform_no_reclaim(ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 //------------------------rethrow_exceptions-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // Bind all exception states in the list into a single RethrowNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
767 void Compile::rethrow_exceptions(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 if (!kit.has_exceptions()) return; // nothing to generate
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // Load my combined exception state into the kit, with all phis transformed:
a61af66fc99e Initial load
duke
parents:
diff changeset
771 SafePointNode* ex_map = kit.combine_and_pop_all_exception_states();
a61af66fc99e Initial load
duke
parents:
diff changeset
772 Node* ex_oop = kit.use_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
773 RethrowNode* exit = new (this, TypeFunc::Parms + 1) RethrowNode(kit.control(),
a61af66fc99e Initial load
duke
parents:
diff changeset
774 kit.i_o(), kit.reset_memory(),
a61af66fc99e Initial load
duke
parents:
diff changeset
775 kit.frameptr(), kit.returnadr(),
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // like a return but with exception input
a61af66fc99e Initial load
duke
parents:
diff changeset
777 ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // bind to root
a61af66fc99e Initial load
duke
parents:
diff changeset
779 root()->add_req(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
780 record_for_igvn(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 initial_gvn()->transform_no_reclaim(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 bool Parse::can_rerun_bytecode() {
a61af66fc99e Initial load
duke
parents:
diff changeset
785 switch (bc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
786 case Bytecodes::_ldc:
a61af66fc99e Initial load
duke
parents:
diff changeset
787 case Bytecodes::_ldc_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
788 case Bytecodes::_ldc2_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
789 case Bytecodes::_getfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
790 case Bytecodes::_putfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
791 case Bytecodes::_getstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
792 case Bytecodes::_putstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
793 case Bytecodes::_arraylength:
a61af66fc99e Initial load
duke
parents:
diff changeset
794 case Bytecodes::_baload:
a61af66fc99e Initial load
duke
parents:
diff changeset
795 case Bytecodes::_caload:
a61af66fc99e Initial load
duke
parents:
diff changeset
796 case Bytecodes::_iaload:
a61af66fc99e Initial load
duke
parents:
diff changeset
797 case Bytecodes::_saload:
a61af66fc99e Initial load
duke
parents:
diff changeset
798 case Bytecodes::_faload:
a61af66fc99e Initial load
duke
parents:
diff changeset
799 case Bytecodes::_aaload:
a61af66fc99e Initial load
duke
parents:
diff changeset
800 case Bytecodes::_laload:
a61af66fc99e Initial load
duke
parents:
diff changeset
801 case Bytecodes::_daload:
a61af66fc99e Initial load
duke
parents:
diff changeset
802 case Bytecodes::_bastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
803 case Bytecodes::_castore:
a61af66fc99e Initial load
duke
parents:
diff changeset
804 case Bytecodes::_iastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
805 case Bytecodes::_sastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
806 case Bytecodes::_fastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
807 case Bytecodes::_aastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
808 case Bytecodes::_lastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
809 case Bytecodes::_dastore:
a61af66fc99e Initial load
duke
parents:
diff changeset
810 case Bytecodes::_irem:
a61af66fc99e Initial load
duke
parents:
diff changeset
811 case Bytecodes::_idiv:
a61af66fc99e Initial load
duke
parents:
diff changeset
812 case Bytecodes::_lrem:
a61af66fc99e Initial load
duke
parents:
diff changeset
813 case Bytecodes::_ldiv:
a61af66fc99e Initial load
duke
parents:
diff changeset
814 case Bytecodes::_frem:
a61af66fc99e Initial load
duke
parents:
diff changeset
815 case Bytecodes::_fdiv:
a61af66fc99e Initial load
duke
parents:
diff changeset
816 case Bytecodes::_drem:
a61af66fc99e Initial load
duke
parents:
diff changeset
817 case Bytecodes::_ddiv:
a61af66fc99e Initial load
duke
parents:
diff changeset
818 case Bytecodes::_checkcast:
a61af66fc99e Initial load
duke
parents:
diff changeset
819 case Bytecodes::_instanceof:
a61af66fc99e Initial load
duke
parents:
diff changeset
820 case Bytecodes::_athrow:
a61af66fc99e Initial load
duke
parents:
diff changeset
821 case Bytecodes::_anewarray:
a61af66fc99e Initial load
duke
parents:
diff changeset
822 case Bytecodes::_newarray:
a61af66fc99e Initial load
duke
parents:
diff changeset
823 case Bytecodes::_multianewarray:
a61af66fc99e Initial load
duke
parents:
diff changeset
824 case Bytecodes::_new:
a61af66fc99e Initial load
duke
parents:
diff changeset
825 case Bytecodes::_monitorenter: // can re-run initial null check, only
a61af66fc99e Initial load
duke
parents:
diff changeset
826 case Bytecodes::_return:
a61af66fc99e Initial load
duke
parents:
diff changeset
827 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
829
a61af66fc99e Initial load
duke
parents:
diff changeset
830 case Bytecodes::_invokestatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
831 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
832 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
833 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
834 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
835 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
838 assert(false, "unexpected bytecode produced an exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
839 return true;
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 //---------------------------do_exceptions-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
844 // Process exceptions arising from the current bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // Send caught exceptions to the proper handler within this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // Unhandled exceptions feed into _exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
847 void Parse::do_exceptions() {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 if (!has_exceptions()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 if (failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // Pop them all off and throw them away.
a61af66fc99e Initial load
duke
parents:
diff changeset
852 while (pop_exception_state() != NULL) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
853 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Make sure we can classify this bytecode if we need to.
a61af66fc99e Initial load
duke
parents:
diff changeset
857 debug_only(can_rerun_bytecode());
a61af66fc99e Initial load
duke
parents:
diff changeset
858
a61af66fc99e Initial load
duke
parents:
diff changeset
859 PreserveJVMState pjvms(this, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 SafePointNode* ex_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
862 while ((ex_map = pop_exception_state()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
863 if (!method()->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // Common case: Transfer control outward.
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // Doing it this early allows the exceptions to common up
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // even between adjacent method calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
867 throw_to_exit(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
868 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // Have to look at the exception first.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 assert(stopped(), "catch_inline_exceptions trashes the map");
a61af66fc99e Initial load
duke
parents:
diff changeset
871 catch_inline_exceptions(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
872 stop_and_kill_map(); // we used up this exception state; kill it
a61af66fc99e Initial load
duke
parents:
diff changeset
873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // We now return to our regularly scheduled program:
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 //---------------------------throw_to_exit-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // Merge the given map into an exception exit from this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // The exception exit will handle any unlocking of receiver.
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // The ex_oop must be saved within the ex_map, unlike merge_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
883 void Parse::throw_to_exit(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // Pop the JVMS to (a copy of) the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
885 GraphKit caller;
a61af66fc99e Initial load
duke
parents:
diff changeset
886 caller.set_map_clone(_caller->map());
a61af66fc99e Initial load
duke
parents:
diff changeset
887 caller.set_bci(_caller->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
888 caller.set_sp(_caller->sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // Copy out the standard machine state:
a61af66fc99e Initial load
duke
parents:
diff changeset
890 for (uint i = 0; i < TypeFunc::Parms; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 caller.map()->set_req(i, ex_map->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // ...and the exception:
a61af66fc99e Initial load
duke
parents:
diff changeset
894 Node* ex_oop = saved_ex_oop(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 SafePointNode* caller_ex_map = caller.make_exception_state(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // Finally, collect the new exception state in my exits:
a61af66fc99e Initial load
duke
parents:
diff changeset
897 _exits.add_exception_state(caller_ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 //------------------------------do_exits---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
901 void Parse::do_exits() {
a61af66fc99e Initial load
duke
parents:
diff changeset
902 set_parse_bci(InvocationEntryBci);
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // Now peephole on the return bits
a61af66fc99e Initial load
duke
parents:
diff changeset
905 Node* region = _exits.control();
a61af66fc99e Initial load
duke
parents:
diff changeset
906 _exits.set_control(gvn().transform(region));
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 Node* iophi = _exits.i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
909 _exits.set_i_o(gvn().transform(iophi));
a61af66fc99e Initial load
duke
parents:
diff changeset
910
a61af66fc99e Initial load
duke
parents:
diff changeset
911 if (wrote_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // This method (which must be a constructor by the rules of Java)
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // wrote a final. The effects of all initializations must be
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // committed to memory before any code after the constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
915 // publishes the reference to the newly constructor object.
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // Rather than wait for the publication, we simply block the
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // writes here. Rather than put a barrier on only those writes
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // which are required to complete, we force all writes to complete.
a61af66fc99e Initial load
duke
parents:
diff changeset
919 //
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // "All bets are off" unless the first publication occurs after a
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // normal return from the constructor. We do not attempt to detect
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // such unusual early publications. But no barrier is needed on
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // exceptional returns, since they cannot publish normally.
a61af66fc99e Initial load
duke
parents:
diff changeset
924 //
a61af66fc99e Initial load
duke
parents:
diff changeset
925 _exits.insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
926 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
927 if (PrintOpto && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 method()->print_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
929 tty->print_cr(" writes finals and needs a memory barrier");
a61af66fc99e Initial load
duke
parents:
diff changeset
930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
931 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 for (MergeMemStream mms(_exits.merged_memory()); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // transform each slice of the original memphi:
a61af66fc99e Initial load
duke
parents:
diff changeset
936 mms.set_memory(_gvn.transform(mms.memory()));
a61af66fc99e Initial load
duke
parents:
diff changeset
937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
938
a61af66fc99e Initial load
duke
parents:
diff changeset
939 if (tf()->range()->cnt() > TypeFunc::Parms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
941 Node* ret_phi = _gvn.transform( _exits.argument(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
942 assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined");
a61af66fc99e Initial load
duke
parents:
diff changeset
943 _exits.push_node(ret_type->basic_type(), ret_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // Note: Logic for creating and optimizing the ReturnNode is in Compile.
a61af66fc99e Initial load
duke
parents:
diff changeset
947
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // Unlock along the exceptional paths.
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // This is done late so that we can common up equivalent exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // (e.g., null checks) arising from multiple points within this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // See GraphKit::add_exception_state, which performs the commoning.
a61af66fc99e Initial load
duke
parents:
diff changeset
952 bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode;
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // record exit from a method if compiled while Dtrace is turned on.
a61af66fc99e Initial load
duke
parents:
diff changeset
955 if (do_synch || DTraceMethodProbes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // First move the exception list out of _exits:
a61af66fc99e Initial load
duke
parents:
diff changeset
957 GraphKit kit(_exits.transfer_exceptions_into_jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
958 SafePointNode* normal_map = kit.map(); // keep this guy safe
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // Now re-collect the exceptions into _exits:
a61af66fc99e Initial load
duke
parents:
diff changeset
960 SafePointNode* ex_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 while ((ex_map = kit.pop_exception_state()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
962 Node* ex_oop = kit.use_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // Force the exiting JVM state to have this method at InvocationEntryBci.
a61af66fc99e Initial load
duke
parents:
diff changeset
964 // The exiting JVM state is otherwise a copy of the calling JVMS.
a61af66fc99e Initial load
duke
parents:
diff changeset
965 JVMState* caller = kit.jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
966 JVMState* ex_jvms = caller->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
967 ex_jvms->set_map(kit.clone_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
968 ex_jvms->map()->set_jvms(ex_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
969 ex_jvms->set_bci( InvocationEntryBci);
a61af66fc99e Initial load
duke
parents:
diff changeset
970 kit.set_jvms(ex_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if (do_synch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // Add on the synchronized-method box/object combo
a61af66fc99e Initial load
duke
parents:
diff changeset
973 kit.map()->push_monitor(_synch_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // Unlock!
a61af66fc99e Initial load
duke
parents:
diff changeset
975 kit.shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977 if (DTraceMethodProbes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
978 kit.make_dtrace_method_exit(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // Done with exception-path processing.
a61af66fc99e Initial load
duke
parents:
diff changeset
981 ex_map = kit.make_exception_state(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
982 assert(ex_jvms->same_calls_as(ex_map->jvms()), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // Pop the last vestige of this method:
a61af66fc99e Initial load
duke
parents:
diff changeset
984 ex_map->set_jvms(caller->clone_shallow(C));
a61af66fc99e Initial load
duke
parents:
diff changeset
985 ex_map->jvms()->set_map(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 _exits.push_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
988 assert(_exits.map() == normal_map, "keep the same return state");
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990
a61af66fc99e Initial load
duke
parents:
diff changeset
991 {
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // Capture very early exceptions (receiver null checks) from caller JVMS
a61af66fc99e Initial load
duke
parents:
diff changeset
993 GraphKit caller(_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
994 SafePointNode* ex_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 while ((ex_map = caller.pop_exception_state()) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 _exits.add_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 //-----------------------------create_entry_map-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 // Initialize our parser map to contain the types at method entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 // For OSR, the map contains a single RawPtr parameter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // Initial monitor locking for sync. methods is performed by do_method_entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 SafePointNode* Parse::create_entry_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 // Check for really stupid bail-out cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 uint len = TypeFunc::Parms + method()->max_locals() + method()->max_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 if (len >= 32760) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 C->record_method_not_compilable_all_tiers("too many local variables");
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1012
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // If this is an inlined method, we may have to do a receiver null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 if (_caller->has_method() && is_normal_parse() && !method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 GraphKit kit(_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 kit.null_check_receiver(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 _caller = kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 _exits.add_exception_states_from(_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 _exits.set_jvms(_caller);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 assert(method() != NULL, "parser must have a method");
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // Create an initial safepoint to hold JVM state during parsing
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 JVMState* jvms = new (C) JVMState(method(), _caller->has_method() ? _caller : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 set_map(new (C, len) SafePointNode(len, jvms));
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 jvms->set_map(map());
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 record_for_igvn(map());
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 assert(jvms->endoff() == len, "correct jvms sizing");
a61af66fc99e Initial load
duke
parents:
diff changeset
1033
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 SafePointNode* inmap = _caller->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 assert(inmap != NULL, "must have inmap");
a61af66fc99e Initial load
duke
parents:
diff changeset
1036
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // Pass thru the predefined input parameters.
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 for (i = 0; i < TypeFunc::Parms; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 map()->init_req(i, inmap->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 if (depth() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 assert(map()->memory()->Opcode() == Op_Parm, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // Insert the memory aliasing node
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 set_all_memory(reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 assert(merged_memory(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // Now add the locals which are initially bound to arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 uint arg_size = tf()->domain()->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 ensure_stack(arg_size - TypeFunc::Parms); // OSR methods have funny args
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 for (i = TypeFunc::Parms; i < arg_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 map()->init_req(i, inmap->argument(_caller, i - TypeFunc::Parms));
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // Clear out the rest of the map (locals and stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 for (i = arg_size; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 map()->init_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1062
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 SafePointNode* entry_map = stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 return entry_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 //-----------------------------do_method_entry--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // Emit any code needed in the pseudo-block before BCI zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // The main thing to do is lock the receiver of a synchronized method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 void Parse::do_method_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 set_parse_bci(InvocationEntryBci); // Pseudo-BCP
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 set_sp(0); // Java Stack Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 NOT_PRODUCT( count_compiled_calls(true/*at_method_entry*/, false/*is_inline*/); )
a61af66fc99e Initial load
duke
parents:
diff changeset
1075
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 if (DTraceMethodProbes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 make_dtrace_method_entry(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // If the method is synchronized, we need to construct a lock node, attach
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // it to the Start node, and pin it there.
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 if (method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // Insert a FastLockNode right after the Start which takes as arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // the current thread pointer, the "this" pointer & the address of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // stack slot pair used for the lock. The "this" pointer is a projection
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // off the start node, but the locking spot has to be constructed by
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // creating a ConLNode of 0, and boxing it with a BoxLockNode. The BoxLockNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // becomes the second argument to the FastLockNode call. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // FastLockNode becomes the new control parent to pin it to the start.
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // Setup Object Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 Node *lock_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 if(method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 ciInstance* mirror = _method->holder()->java_mirror();
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 const TypeInstPtr *t_lock = TypeInstPtr::make(mirror);
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 lock_obj = makecon(t_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 } else { // Else pass the "this" pointer,
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 lock_obj = local(0); // which is Parm0 from StartNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 // Clear out dead values from the debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // Build the FastLockNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 _synch_lock = shared_lock(lock_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 if (depth() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 increment_and_test_invocation_counter(Tier2CompileThreshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 //------------------------------init_blocks------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // Initialize our parser map to contain the types/monitors at method entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 void Parse::init_blocks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 // Create the blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 _block_count = flow()->block_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 _blocks = NEW_RESOURCE_ARRAY(Block, _block_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 Copy::zero_to_bytes(_blocks, sizeof(Block)*_block_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1119 int rpo;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1120
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // Initialize the structs.
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1122 for (rpo = 0; rpo < block_count(); rpo++) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1123 Block* block = rpo_at(rpo);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1124 block->init_node(this, rpo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // Collect predecessor and successor information.
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1128 for (rpo = 0; rpo < block_count(); rpo++) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1129 Block* block = rpo_at(rpo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 block->init_graph(this);
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 //-------------------------------init_node-------------------------------------
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1135 void Parse::Block::init_node(Parse* outer, int rpo) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1136 _flow = outer->flow()->rpo_at(rpo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 _pred_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 _preds_parsed = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 _count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 assert(pred_count() == 0 && preds_parsed() == 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 assert(!(is_merged() || is_parsed() || is_handler()), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 assert(_live_locals.size() == 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1143
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // entry point has additional predecessor
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 if (flow()->is_start()) _pred_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 assert(flow()->is_start() == (this == outer->start_block()), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 //-------------------------------init_graph------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 void Parse::Block::init_graph(Parse* outer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // Create the successor list for this parser block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 GrowableArray<ciTypeFlow::Block*>* tfs = flow()->successors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 GrowableArray<ciTypeFlow::Block*>* tfe = flow()->exceptions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 int ns = tfs->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 int ne = tfe->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 _num_successors = ns;
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 _all_successors = ns+ne;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 _successors = (ns+ne == 0) ? NULL : NEW_RESOURCE_ARRAY(Block*, ns+ne);
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 int p = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 for (int i = 0; i < ns+ne; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 ciTypeFlow::Block* tf2 = (i < ns) ? tfs->at(i) : tfe->at(i-ns);
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1162 Block* block2 = outer->rpo_at(tf2->rpo());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 _successors[i] = block2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // Accumulate pred info for the other block, too.
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 if (i < ns) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 block2->_pred_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 block2->_is_handler = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1171
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // A block's successors must be distinguishable by BCI.
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // That is, no bytecode is allowed to branch to two different
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // clones of the same code location.
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 for (int j = 0; j < i; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 Block* block1 = _successors[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 if (block1 == block2) continue; // duplicates are OK
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 assert(block1->start() != block2->start(), "successors have unique bcis");
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1183
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // Note: We never call next_path_num along exception paths, so they
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // never get processed as "ready". Also, the input phis of exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // handlers get specially processed, so that
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1188
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 //---------------------------successor_for_bci---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 Parse::Block* Parse::Block::successor_for_bci(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 for (int i = 0; i < all_successors(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 Block* block2 = successor_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 if (block2->start() == bci) return block2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // We can actually reach here if ciTypeFlow traps out a block
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // due to an unloaded class, and concurrently with compilation the
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // class is then loaded, so that a later phase of the parser is
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // able to see more of the bytecode CFG. Or, the flow pass and
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // the parser can have a minor difference of opinion about executability
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // of bytecodes. For example, "obj.field = null" is executable even
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // if the field's type is an unloaded class; the flow pass used to
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // make a trap for such code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 //-----------------------------stack_type_at-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 const Type* Parse::Block::stack_type_at(int i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 return get_type(flow()->stack_type_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1211
a61af66fc99e Initial load
duke
parents:
diff changeset
1212
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 //-----------------------------local_type_at-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 const Type* Parse::Block::local_type_at(int i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // Make dead locals fall to bottom.
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 if (_live_locals.size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 MethodLivenessResult live_locals = flow()->outer()->method()->liveness_at_bci(start());
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // This bitmap can be zero length if we saw a breakpoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // In such cases, pretend they are all live.
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 ((Block*)this)->_live_locals = live_locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 if (_live_locals.size() > 0 && !_live_locals.at(i))
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 return Type::BOTTOM;
a61af66fc99e Initial load
duke
parents:
diff changeset
1224
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 return get_type(flow()->local_type_at(i));
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 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1230
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 //----------------------------name_for_bc--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // helper method for BytecodeParseHistogram
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 static const char* name_for_bc(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 return Bytecodes::is_defined(i) ? Bytecodes::name(Bytecodes::cast(i)) : "xxxunusedxxx";
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 //----------------------------BytecodeParseHistogram------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 Parse::BytecodeParseHistogram::BytecodeParseHistogram(Parse *p, Compile *c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 _parser = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 _compiler = c;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 if( ! _initialized ) { _initialized = true; reset(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 //----------------------------current_count------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 int Parse::BytecodeParseHistogram::current_count(BPHType bph_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 switch( bph_type ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 case BPH_transforms: { return _parser->gvn().made_progress(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 case BPH_values: { return _parser->gvn().made_new_values(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 default: { ShouldNotReachHere(); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 //----------------------------initialized--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 bool Parse::BytecodeParseHistogram::initialized() { return _initialized; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1255
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 //----------------------------reset--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 void Parse::BytecodeParseHistogram::reset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 int i = Bytecodes::number_of_codes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 while (i-- > 0) { _bytecodes_parsed[i] = 0; _nodes_constructed[i] = 0; _nodes_transformed[i] = 0; _new_values[i] = 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 //----------------------------set_initial_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Record info when starting to parse one bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 void Parse::BytecodeParseHistogram::set_initial_state( Bytecodes::Code bc ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 if( PrintParseStatistics && !_parser->is_osr_parse() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 _initial_bytecode = bc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 _initial_node_count = _compiler->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 _initial_transforms = current_count(BPH_transforms);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 _initial_values = current_count(BPH_values);
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 //----------------------------record_change--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Record results of parsing one bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 void Parse::BytecodeParseHistogram::record_change() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 if( PrintParseStatistics && !_parser->is_osr_parse() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 ++_bytecodes_parsed[_initial_bytecode];
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 _nodes_constructed [_initial_bytecode] += (_compiler->unique() - _initial_node_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 _nodes_transformed [_initial_bytecode] += (current_count(BPH_transforms) - _initial_transforms);
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 _new_values [_initial_bytecode] += (current_count(BPH_values) - _initial_values);
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1283
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 //----------------------------print--------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 void Parse::BytecodeParseHistogram::print(float cutoff) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // print profile
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 int total = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 for( i = 0; i < Bytecodes::number_of_codes; ++i ) { total += _bytecodes_parsed[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 int abs_sum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 tty->cr(); //0123456789012345678901234567890123456789012345678901234567890123456789
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 tty->print_cr("Histogram of %d parsed bytecodes:", total);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 if( total == 0 ) { return; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 tty->print_cr("absolute: count of compiled bytecodes of this type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 tty->print_cr("relative: percentage contribution to compiled nodes");
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 tty->print_cr("nodes : Average number of nodes constructed per bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 tty->print_cr("rnodes : Significance towards total nodes constructed, (nodes*relative)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 tty->print_cr("transforms: Average amount of tranform progress per bytecode compiled");
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 tty->print_cr("values : Average number of node values improved per bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 tty->print_cr("name : Bytecode name");
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 tty->print_cr(" absolute relative nodes rnodes transforms values name");
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 tty->print_cr("----------------------------------------------------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 while (--i > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 int abs = _bytecodes_parsed[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 float rel = abs * 100.0F / total;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 float nodes = _bytecodes_parsed[i] == 0 ? 0 : (1.0F * _nodes_constructed[i])/_bytecodes_parsed[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 float rnodes = _bytecodes_parsed[i] == 0 ? 0 : rel * nodes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 float xforms = _bytecodes_parsed[i] == 0 ? 0 : (1.0F * _nodes_transformed[i])/_bytecodes_parsed[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 float values = _bytecodes_parsed[i] == 0 ? 0 : (1.0F * _new_values [i])/_bytecodes_parsed[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 if (cutoff <= rel) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 tty->print_cr("%10d %7.2f%% %6.1f %6.2f %6.1f %6.1f %s", abs, rel, nodes, rnodes, xforms, values, name_for_bc(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 abs_sum += abs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 tty->print_cr("----------------------------------------------------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 float rel_sum = abs_sum * 100.0F / total;
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 tty->print_cr("%10d %7.2f%% (cutoff = %.2f%%)", abs_sum, rel_sum, cutoff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 tty->print_cr("----------------------------------------------------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1326
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 //----------------------------load_state_from----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // Load block/map/sp. But not do not touch iter/bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 void Parse::load_state_from(Block* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 set_block(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // load the block's JVM state:
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 set_map(block->start_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 set_sp( block->start_sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 //-----------------------------record_state------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 void Parse::Block::record_state(Parse* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 assert(!is_merged(), "can only record state once, on 1st inflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 assert(start_sp() == p->sp(), "stack pointer must agree with ciTypeFlow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 set_start_map(p->stop());
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 //------------------------------do_one_block-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 void Parse::do_one_block() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if (TraceOptoParse) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 Block *b = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 int ns = b->num_successors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 int nt = b->all_successors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 tty->print("Parsing block #%d at bci [%d,%d), successors: ",
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1353 block()->rpo(), block()->start(), block()->limit());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 for (int i = 0; i < nt; i++) {
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1355 tty->print((( i < ns) ? " %d" : " %d(e)"), b->successor_at(i)->rpo());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 }
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1357 if (b->is_loop_head()) tty->print(" lphd");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1360
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 assert(block()->is_merged(), "must be merged before being parsed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 block()->mark_parsed();
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 ++_blocks_parsed;
a61af66fc99e Initial load
duke
parents:
diff changeset
1364
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 // Set iterator to start of block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 iter().reset_to_bci(block()->start());
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 CompileLog* log = C->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
1369
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // Parse bytecodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 while (!stopped() && !failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 iter().next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1373
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // Learn the current bci from the iterator:
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 set_parse_bci(iter().cur_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 if (bci() == block()->limit()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // Do not walk into the next block until directed by do_all_blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 merge(bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 assert(bci() < block()->limit(), "bci still in block");
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // Output an optional context marker, to help place actions
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // that occur during parsing of this BC. If there is no log
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // output until the next context string, this context string
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // will be silently ignored.
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 log->context()->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 log->context()->print_cr("<bc code='%d' bci='%d'/>", (int)bc(), bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1392
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 if (block()->has_trap_at(bci())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // We must respect the flow pass's traps, because it will refuse
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // to produce successors for trapping blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 int trap_index = block()->flow()->trap_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 assert(trap_index != 0, "trap index must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 uncommon_trap(trap_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1401
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 NOT_PRODUCT( parse_histogram()->set_initial_state(bc()); );
a61af66fc99e Initial load
duke
parents:
diff changeset
1403
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 int pre_bc_sp = sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 int inputs, depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 bool have_se = !stopped() && compute_stack_effects(inputs, depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 assert(!have_se || pre_bc_sp >= inputs, "have enough stack to execute this BC");
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1410
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 do_one_bytecode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1412
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth, "correct depth prediction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1414
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 do_exceptions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1416
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 NOT_PRODUCT( parse_histogram()->record_change(); );
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 if (log != NULL) log->context()->reset(); // done w/ this one
a61af66fc99e Initial load
duke
parents:
diff changeset
1420
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // Fall into next bytecode. Each bytecode normally has 1 sequential
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 // successor which is typically made ready by visiting this bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // If the successor has several predecessors, then it is a merge
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // point, starts a new basic block, and is handled like other basic blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1427
a61af66fc99e Initial load
duke
parents:
diff changeset
1428
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 //------------------------------merge------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 void Parse::set_parse_bci(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 set_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 Node_Notes* nn = C->default_node_notes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if (nn == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1434
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // Collect debug info for inlined calls unless -XX:-DebugInlinedCalls.
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if (!DebugInlinedCalls && depth() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1439
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 // Update the JVMS annotation, if present.
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 JVMState* jvms = nn->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 if (jvms != NULL && jvms->bci() != bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 // Update the JVMS.
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 jvms = jvms->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 jvms->set_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 nn->set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1449
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 //------------------------------merge------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Merge the current mapping into the basic block starting at bci
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 void Parse::merge(int target_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 Block* target = successor_for_bci(target_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 if (target == NULL) { handle_missing_successor(target_bci); return; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 assert(!target->is_ready(), "our arrival must be expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 int pnum = target->next_path_num();
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 merge_common(target, pnum);
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1459
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 //-------------------------merge_new_path--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // Merge the current mapping into the basic block, using a new path
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 void Parse::merge_new_path(int target_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 Block* target = successor_for_bci(target_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 if (target == NULL) { handle_missing_successor(target_bci); return; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 assert(!target->is_ready(), "new path into frozen graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 int pnum = target->add_new_path();
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 merge_common(target, pnum);
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1469
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 //-------------------------merge_exception-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 // Merge the current mapping into the basic block starting at bci
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // The ex_oop must be pushed on the stack, unlike throw_to_exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 void Parse::merge_exception(int target_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 assert(sp() == 1, "must have only the throw exception on the stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 Block* target = successor_for_bci(target_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 if (target == NULL) { handle_missing_successor(target_bci); return; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 assert(target->is_handler(), "exceptions are handled by special blocks");
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 int pnum = target->add_new_path();
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 merge_common(target, pnum);
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1481
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 //--------------------handle_missing_successor---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 void Parse::handle_missing_successor(int target_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 Block* b = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 int trap_bci = b->flow()->has_trap()? b->flow()->trap_bci(): -1;
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1487 tty->print_cr("### Missing successor at bci:%d for block #%d (trap_bci:%d)", target_bci, b->rpo(), trap_bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1491
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 //--------------------------merge_common---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 void Parse::merge_common(Parse::Block* target, int pnum) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 if (TraceOptoParse) {
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1495 tty->print("Merging state at block #%d bci:%d", target->rpo(), target->start());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // Zap extra stack slots to top
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 assert(sp() == target->start_sp(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 clean_stack(sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 if (!target->is_merged()) { // No prior mapping at this bci
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 if (TraceOptoParse) { tty->print(" with empty state"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // If this path is dead, do not bother capturing it as a merge.
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // It is "as if" we had 1 fewer predecessors from the beginning.
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 if (TraceOptoParse) tty->print_cr(", but path is dead and doesn't count");
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1511
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 // Record that a new block has been merged.
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 ++_blocks_merged;
a61af66fc99e Initial load
duke
parents:
diff changeset
1514
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // Make a region if we know there are multiple or unpredictable inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // (Also, if this is a plain fall-through, we might see another region,
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // which must not be allowed into this block's map.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 if (pnum > PhiNode::Input // Known multiple inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 || target->is_handler() // These have unpredictable inputs.
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1520 || target->is_loop_head() // Known multiple inputs
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 || control()->is_Region()) { // We must hide this guy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // Add a Region to start the new basic block. Phis will be added
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // later lazily.
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 int edges = target->pred_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 if (edges < pnum) edges = pnum; // might be a new path!
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 Node *r = new (C, edges+1) RegionNode(edges+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 gvn().set_type(r, Type::CONTROL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 record_for_igvn(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // zap all inputs to NULL for debugging (done in Node(uint) constructor)
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 // for (int j = 1; j < edges+1; j++) { r->init_req(j, NULL); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 r->init_req(pnum, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 set_control(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // Convert the existing Parser mapping into a mapping at this bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 store_state_to(target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 assert(target->is_merged(), "do not come here twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 } else { // Prior mapping at this bci
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 if (TraceOptoParse) { tty->print(" with previous state"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1541
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // We must not manufacture more phis if the target is already parsed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 bool nophi = target->is_parsed();
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 SafePointNode* newin = map();// Hang on to incoming mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 Block* save_block = block(); // Hang on to incoming block;
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 load_state_from(target); // Get prior mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 assert(newin->jvms()->locoff() == jvms()->locoff(), "JVMS layouts agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 assert(newin->jvms()->stkoff() == jvms()->stkoff(), "JVMS layouts agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 assert(newin->jvms()->monoff() == jvms()->monoff(), "JVMS layouts agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 assert(newin->jvms()->endoff() == jvms()->endoff(), "JVMS layouts agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
1553
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // Iterate over my current mapping and the old mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // Where different, insert Phi functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // Use any existing Phi functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 assert(control()->is_Region(), "must be merging to a region");
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 RegionNode* r = control()->as_Region();
a61af66fc99e Initial load
duke
parents:
diff changeset
1559
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // Compute where to merge into
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // Merge incoming control path
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1562 r->init_req(pnum, newin->control());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1563
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 if (pnum == 1) { // Last merge for this Region?
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1565 if (!block()->flow()->is_irreducible_entry()) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1566 Node* result = _gvn.transform_no_reclaim(r);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1567 if (r != result && TraceOptoParse) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1568 tty->print_cr("Block #%d replace %d with %d", block()->rpo(), r->_idx, result->_idx);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1569 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1570 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 record_for_igvn(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // Update all the non-control inputs to map:
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 assert(TypeFunc::Parms == newin->jvms()->locoff(), "parser map should contain only youngest jvms");
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1576 bool check_elide_phi = target->is_SEL_backedge(save_block);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 for (uint j = 1; j < newin->req(); j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 Node* m = map()->in(j); // Current state of target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 Node* n = newin->in(j); // Incoming change to target state.
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 if (m->is_Phi() && m->as_Phi()->region() == r)
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 phi = m->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 phi = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 if (m != n) { // Different; must merge
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 switch (j) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // Frame pointer and Return Address never changes
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 case TypeFunc::FramePtr:// Drop m, use the original value
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 case TypeFunc::ReturnAdr:
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 case TypeFunc::Memory: // Merge inputs to the MergeMem node
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 assert(phi == NULL, "the merge contains phis, not vice versa");
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 merge_memory_edges(n->as_MergeMem(), pnum, nophi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 default: // All normal stuff
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1596 if (phi == NULL) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1597 if (!check_elide_phi || !target->can_elide_SEL_phi(j)) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1598 phi = ensure_phi(j, nophi);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1599 }
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1600 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // At this point, n might be top if:
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // - there is no phi (because TypeFlow detected a conflict), or
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // - the corresponding control edges is top (a dead incoming path)
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // It is a bug if we create a phi which sees a garbage value on a live path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1608
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 if (phi != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 assert(n != top() || r->in(pnum) == top(), "live value must not be garbage");
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 assert(phi->region() == r, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 phi->set_req(pnum, n); // Then add 'n' to the merge
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 if (pnum == PhiNode::Input) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // Last merge for this Phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // So far, Phis have had a reasonable type from ciTypeFlow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // Now _gvn will join that with the meet of current inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 // BOTTOM is never permissible here, 'cause pessimistically
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // Phis of pointers cannot lose the basic pointer type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 debug_only(const Type* bt1 = phi->bottom_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 assert(bt1 != Type::BOTTOM, "should not be building conflict phis");
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 map()->set_req(j, _gvn.transform_no_reclaim(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 debug_only(const Type* bt2 = phi->bottom_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 assert(bt2->higher_equal(bt1), "must be consistent with type-flow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 record_for_igvn(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 } // End of for all values to be merged
a61af66fc99e Initial load
duke
parents:
diff changeset
1628
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 if (pnum == PhiNode::Input &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 !r->in(0)) { // The occasional useless Region
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 assert(control() == r, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 set_control(r->nonnull_req());
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1634
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // newin has been subsumed into the lazy merge, and is now dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 set_block(save_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1637
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 stop(); // done with this guy, for now
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1640
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 if (TraceOptoParse) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 tty->print_cr(" on path %d", pnum);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 // Done with this parser state.
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 assert(stopped(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1648
a61af66fc99e Initial load
duke
parents:
diff changeset
1649
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 //--------------------------merge_memory_edges---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 void Parse::merge_memory_edges(MergeMemNode* n, int pnum, bool nophi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // (nophi means we must not create phis, because we already parsed here)
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 assert(n != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // Merge the inputs to the MergeMems
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 MergeMemNode* m = merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1656
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 assert(control()->is_Region(), "must be merging to a region");
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 RegionNode* r = control()->as_Region();
a61af66fc99e Initial load
duke
parents:
diff changeset
1659
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 PhiNode* base = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 MergeMemNode* remerge = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 for (MergeMemStream mms(m, n); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 Node *p = mms.force_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 Node *q = mms.memory2();
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 if (mms.is_empty() && nophi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // Trouble: No new splits allowed after a loop body is parsed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // Instead, wire the new split into a MergeMem on the backedge.
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // The optimizer will sort it out, slicing the phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 if (remerge == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 assert(base != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 assert(base->in(0) != NULL, "should not be xformed away");
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 remerge = MergeMemNode::make(C, base->in(pnum));
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 gvn().set_type(remerge, Type::MEMORY);
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 base->set_req(pnum, remerge);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 remerge->set_memory_at(mms.alias_idx(), q);
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 assert(!q->is_MergeMem(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 if (p != q) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 phi = ensure_memory_phi(mms.alias_idx(), nophi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 if (p->is_Phi() && p->as_Phi()->region() == r)
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 phi = p->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 phi = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // Insert q into local phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 if (phi != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 assert(phi->region() == r, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 p = phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 phi->set_req(pnum, q);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 if (mms.at_base_memory()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 base = phi; // delay transforming it
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 } else if (pnum == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 record_for_igvn(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 p = _gvn.transform_no_reclaim(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 mms.set_memory(p);// store back through the iterator
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // Transform base last, in case we must fiddle with remerging.
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 if (base != NULL && pnum == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 record_for_igvn(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 m->set_base_memory( _gvn.transform_no_reclaim(base) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
a61af66fc99e Initial load
duke
parents:
diff changeset
1710
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 //------------------------ensure_phis_everywhere-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 void Parse::ensure_phis_everywhere() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 ensure_phi(TypeFunc::I_O);
a61af66fc99e Initial load
duke
parents:
diff changeset
1714
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // Ensure a phi on all currently known memories.
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 ensure_memory_phi(mms.alias_idx());
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 debug_only(mms.set_memory()); // keep the iterator happy
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1720
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // Note: This is our only chance to create phis for memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // If we miss a slice that crops up later, it will have to be
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // merged into the base-memory phi that we are building here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // Later, the optimizer will comb out the knot, and build separate
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // phi-loops for each memory slice that matters.
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // Monitors must nest nicely and not get confused amongst themselves.
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // Phi-ify everything up to the monitors, though.
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 uint monoff = map()->jvms()->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 uint nof_monitors = map()->jvms()->nof_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 assert(TypeFunc::Parms == map()->jvms()->locoff(), "parser map should contain only youngest jvms");
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1733 bool check_elide_phi = block()->is_SEL_head();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 for (uint i = TypeFunc::Parms; i < monoff; i++) {
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1735 if (!check_elide_phi || !block()->can_elide_SEL_phi(i)) {
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1736 ensure_phi(i);
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1737 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 }
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
1739
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 // Even monitors need Phis, though they are well-structured.
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 // This is true for OSR methods, and also for the rare cases where
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 // a monitor object is the subject of a replace_in_map operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // See bugs 4426707 and 5043395.
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 for (uint m = 0; m < nof_monitors; m++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 ensure_phi(map()->jvms()->monitor_obj_offset(m));
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1748
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 //-----------------------------add_new_path------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // Add a previously unaccounted predecessor to this block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 int Parse::Block::add_new_path() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // If there is no map, return the lowest unused path number.
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 if (!is_merged()) return pred_count()+1; // there will be a map shortly
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 SafePointNode* map = start_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 if (!map->control()->is_Region())
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 return pred_count()+1; // there may be a region some day
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 RegionNode* r = map->control()->as_Region();
a61af66fc99e Initial load
duke
parents:
diff changeset
1760
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // Add new path to the region.
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 uint pnum = r->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 r->add_req(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 for (uint i = 1; i < map->req(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 Node* n = map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 if (i == TypeFunc::Memory) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // Ensure a phi on all currently known memories.
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 for (MergeMemStream mms(n->as_MergeMem()); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 Node* phi = mms.memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 if (phi->is_Phi() && phi->as_Phi()->region() == r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 assert(phi->req() == pnum, "must be same size as region");
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 phi->add_req(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 if (n->is_Phi() && n->as_Phi()->region() == r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 assert(n->req() == pnum, "must be same size as region");
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 n->add_req(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 return pnum;
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1786
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 //------------------------------ensure_phi-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // Turn the idx'th entry of the current map into a Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 PhiNode *Parse::ensure_phi(int idx, bool nocreate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 SafePointNode* map = this->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 Node* region = map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 assert(region->is_Region(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1793
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 Node* o = map->in(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 assert(o != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1796
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 if (o == top()) return NULL; // TOP always merges into TOP
a61af66fc99e Initial load
duke
parents:
diff changeset
1798
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 if (o->is_Phi() && o->as_Phi()->region() == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 return o->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1802
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // Now use a Phi here for merging
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 assert(!nocreate, "Cannot build a phi for a block already parsed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 const JVMState* jvms = map->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 const Type* t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 if (jvms->is_loc(idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 t = block()->local_type_at(idx - jvms->locoff());
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 } else if (jvms->is_stk(idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 t = block()->stack_type_at(idx - jvms->stkoff());
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 } else if (jvms->is_mon(idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 assert(!jvms->is_monitor_box(idx), "no phis for boxes");
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 t = TypeInstPtr::BOTTOM; // this is sufficient for a lock object
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 } else if ((uint)idx < TypeFunc::Parms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 t = o->bottom_type(); // Type::RETURN_ADDRESS or such-like.
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 assert(false, "no type information for this phi");
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1819
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 // If the type falls to bottom, then this must be a local that
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 // is mixing ints and oops or some such. Forcing it to top
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // makes it go dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 if (t == Type::BOTTOM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 map->set_req(idx, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1827
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 // Do not create phis for top either.
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 // A top on a non-null control flow must be an unused even after the.phi.
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 if (t == Type::TOP || t == Type::HALF) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 map->set_req(idx, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1834
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 PhiNode* phi = PhiNode::make(region, o, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 gvn().set_type(phi, t);
38
b789bcaf2dd9 6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents: 0
diff changeset
1837 if (C->do_escape_analysis()) record_for_igvn(phi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 map->set_req(idx, phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1841
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 //--------------------------ensure_memory_phi----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 // Turn the idx'th slice of the current memory into a Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 PhiNode *Parse::ensure_memory_phi(int idx, bool nocreate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 MergeMemNode* mem = merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 Node* region = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 assert(region->is_Region(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1848
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 Node *o = (idx == Compile::AliasIdxBot)? mem->base_memory(): mem->memory_at(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 assert(o != NULL && o != top(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1851
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 if (o->is_Phi() && o->as_Phi()->region() == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 phi = o->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 if (phi == mem->base_memory() && idx >= Compile::AliasIdxRaw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 // clone the shared base memory phi to make a new memory split
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 assert(!nocreate, "Cannot build a phi for a block already parsed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 const Type* t = phi->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 const TypePtr* adr_type = C->get_adr_type(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 phi = phi->slice_memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 gvn().set_type(phi, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 // Now use a Phi here for merging
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 assert(!nocreate, "Cannot build a phi for a block already parsed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 const Type* t = o->bottom_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 const TypePtr* adr_type = C->get_adr_type(idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 phi = PhiNode::make(region, o, t, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 gvn().set_type(phi, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 if (idx == Compile::AliasIdxBot)
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 mem->set_base_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 mem->set_memory_at(idx, phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 return phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1878
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 //------------------------------call_register_finalizer-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // Check the klass of the receiver and call register_finalizer if the
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 // class need finalization.
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 void Parse::call_register_finalizer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 Node* receiver = local(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 assert(receiver != NULL && receiver->bottom_type()->isa_instptr() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 "must have non-null instance type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1886
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 const TypeInstPtr *tinst = receiver->bottom_type()->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 if (tinst != NULL && tinst->klass()->is_loaded() && !tinst->klass_is_exact()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // The type isn't known exactly so see if CHA tells us anything.
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 ciInstanceKlass* ik = tinst->klass()->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 if (!Dependencies::has_finalizable_subclass(ik)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // No finalizable subclasses so skip the dynamic check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 C->dependencies()->assert_has_no_finalizable_subclasses(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1897
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // Insert a dynamic test for whether the instance needs
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 // finalization. In general this will fold up since the concrete
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 // class is often visible so the access flags are constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 Node* klass_addr = basic_plus_adr( receiver, receiver, oopDesc::klass_offset_in_bytes() );
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 38
diff changeset
1902 Node* klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 Node* access_flags_addr = basic_plus_adr(klass, klass, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc));
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1906
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 Node* mask = _gvn.transform(new (C, 3) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 Node* check = _gvn.transform(new (C, 3) CmpINode(mask, intcon(0)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 Node* test = _gvn.transform(new (C, 2) BoolNode(check, BoolTest::ne));
a61af66fc99e Initial load
duke
parents:
diff changeset
1910
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 IfNode* iff = create_and_map_if(control(), test, PROB_MAX, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
1912
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 RegionNode* result_rgn = new (C, 3) RegionNode(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 record_for_igvn(result_rgn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 Node *skip_register = _gvn.transform(new (C, 1) IfFalseNode(iff));
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 result_rgn->init_req(1, skip_register);
a61af66fc99e Initial load
duke
parents:
diff changeset
1918
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 Node *needs_register = _gvn.transform(new (C, 1) IfTrueNode(iff));
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 set_control(needs_register);
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // There is no slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 result_rgn->init_req(2, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 Node *call = make_runtime_call(RC_NO_LEAF,
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 OptoRuntime::register_finalizer_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 OptoRuntime::register_finalizer_Java(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 NULL, TypePtr::BOTTOM,
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 make_slow_call_ex(call, env()->Throwable_klass(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 Node* fast_io = call->in(TypeFunc::I_O);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 Node* fast_mem = call->in(TypeFunc::Memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 // These two phis are pre-filled with copies of of the fast IO and Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 Node* io_phi = PhiNode::make(result_rgn, fast_io, Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 Node* mem_phi = PhiNode::make(result_rgn, fast_mem, Type::MEMORY, TypePtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
1937
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 result_rgn->init_req(2, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 io_phi ->init_req(2, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 mem_phi ->init_req(2, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
1941
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 set_all_memory( _gvn.transform(mem_phi) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 set_i_o( _gvn.transform(io_phi) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1945
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 set_control( _gvn.transform(result_rgn) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 //------------------------------return_current---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // Append current _map to _exit_return
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 void Parse::return_current(Node* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 if (RegisterFinalizersAtInit &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 method()->intrinsic_id() == vmIntrinsics::_Object_init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 call_register_finalizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1956
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // Do not set_parse_bci, so that return goo is credited to the return insn.
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 set_bci(InvocationEntryBci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 if (method()->is_synchronized() && GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node());
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 if (DTraceMethodProbes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 make_dtrace_method_exit(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 SafePointNode* exit_return = _exits.map();
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 exit_return->in( TypeFunc::Control )->add_req( control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 exit_return->in( TypeFunc::I_O )->add_req( i_o () );
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 Node *mem = exit_return->in( TypeFunc::Memory );
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 for (MergeMemStream mms(mem->as_MergeMem(), merged_memory()); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 if (mms.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 // get a copy of the base memory, and patch just this one input
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 const TypePtr* adr_type = mms.adr_type(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 Node* phi = mms.force_memory()->as_Phi()->slice_memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 assert(phi->as_Phi()->region() == mms.base_memory()->in(0), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 gvn().set_type_bottom(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 phi->del_req(phi->req()-1); // prepare to re-patch
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 mms.set_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 mms.memory()->add_req(mms.memory2());
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 // frame pointer is always same, already captured
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 if (value != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 // If returning oops to an interface-return, there is a silent free
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 // cast from oop to interface allowed by the Verifier. Make it explicit
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 // here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 Node* phi = _exits.argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 const TypeInstPtr *tr = phi->bottom_type()->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 if( tr && tr->klass()->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 tr->klass()->is_interface() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 const TypeInstPtr *tp = value->bottom_type()->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 if (tp && tp->klass()->is_loaded() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 !tp->klass()->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // sharpen the type eagerly; this eases certain assert checking
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 if (tp->higher_equal(TypeInstPtr::NOTNULL))
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 tr = tr->join(TypeInstPtr::NOTNULL)->is_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 value = _gvn.transform(new (C, 2) CheckCastPPNode(0,value,tr));
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 phi->add_req(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2002
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 stop_and_kill_map(); // This CFG path dies here
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2005
a61af66fc99e Initial load
duke
parents:
diff changeset
2006
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 //------------------------------add_safepoint----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 void Parse::add_safepoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // See if we can avoid this safepoint. No need for a SafePoint immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 // after a Call (except Leaf Call) or another SafePoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 Node *proj = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 bool add_poll_param = SafePointNode::needs_polling_address_input();
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 uint parms = add_poll_param ? TypeFunc::Parms+1 : TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 if( proj->is_Proj() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 Node *n0 = proj->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 if( n0->is_Catch() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 n0 = n0->in(0)->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 assert( n0->is_Call(), "expect a call here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 if( n0->is_Call() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 if( n0->as_Call()->guaranteed_safepoint() )
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 } else if( n0->is_SafePoint() && n0->req() >= parms ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2027
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 // Clear out dead values from the debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
2030
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // Clone the JVM State
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 SafePointNode *sfpnt = new (C, parms) SafePointNode(parms, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2033
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 // Capture memory state BEFORE a SafePoint. Since we can block at a
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // SafePoint we need our GC state to be safe; i.e. we need all our current
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 // write barriers (card marks) to not float down after the SafePoint so we
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 // must read raw memory. Likewise we need all oop stores to match the card
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 // marks. If deopt can happen, we need ALL stores (we need the correct JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 // state on a deopt).
a61af66fc99e Initial load
duke
parents:
diff changeset
2040
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 // We do not need to WRITE the memory state after a SafePoint. The control
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 // edge will keep card-marks and oop-stores from floating up from below a
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 // SafePoint and our true dependency added here will keep them from floating
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 // down below a SafePoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2045
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 // Clone the current memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 Node* mem = MergeMemNode::make(C, map()->memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
2048
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 mem = _gvn.transform(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 // Pass control through the safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 sfpnt->init_req(TypeFunc::Control , control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // Fix edges normally used by a call
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 sfpnt->init_req(TypeFunc::I_O , top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 sfpnt->init_req(TypeFunc::Memory , mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 sfpnt->init_req(TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 sfpnt->init_req(TypeFunc::FramePtr , top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 // Create a node for the polling address
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 if( add_poll_param ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 Node *polladr = ConPNode::make(C, (address)os::get_polling_page());
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 sfpnt->init_req(TypeFunc::Parms+0, _gvn.transform(polladr));
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2064
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 // Fix up the JVM State edges
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 add_safepoint_edges(sfpnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 Node *transformed_sfpnt = _gvn.transform(sfpnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 set_control(transformed_sfpnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2069
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 // Provide an edge from root to safepoint. This makes the safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // appear useful until the parse has completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 if( OptoRemoveUseless && transformed_sfpnt->is_SafePoint() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 assert(C->root() != NULL, "Expect parse is still valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 C->root()->add_prec(transformed_sfpnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2077
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 //------------------------show_parse_info--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 void Parse::show_parse_info() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 InlineTree* ilt = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 if (C->ilt() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 JVMState* caller_jvms = is_osr_parse() ? caller()->caller() : caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 ilt = InlineTree::find_subtree_from_root(C->ilt(), caller_jvms, method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 if (PrintCompilation && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 if (depth() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 if( ilt->count_inlines() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 tty->print(" __inlined %d (%d bytes)", ilt->count_inlines(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 ilt->count_inline_bcs());
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 if (method()->is_synchronized()) tty->print("s");
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 if (method()->has_exception_handlers()) tty->print("!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // Check this is not the final compiled version
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 if (C->trap_can_recompile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 tty->print("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 method()->print_short_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 if (is_osr_parse()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 tty->print(" @ %d", osr_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 tty->print(" (%d bytes)",method()->code_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 if (ilt->count_inlines()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 tty->print(" __inlined %d (%d bytes)", ilt->count_inlines(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 ilt->count_inline_bcs());
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 if (PrintOpto && (depth() == 1 || PrintOptoInlining)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // Print that we succeeded; suppress this message on the first osr parse.
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 if (method()->is_synchronized()) tty->print("s");
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 if (method()->has_exception_handlers()) tty->print("!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 // Check this is not the final compiled version
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 if (C->trap_can_recompile() && depth() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 tty->print("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 if( depth() != 1 ) { tty->print(" "); } // missing compile count
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 for (int i = 1; i < depth(); ++i) { tty->print(" "); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 method()->print_short_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 if (is_osr_parse()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 tty->print(" @ %d", osr_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 if (ilt->caller_bci() != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 tty->print(" @ %d", ilt->caller_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 tty->print(" (%d bytes)",method()->code_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 if (ilt->count_inlines()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 tty->print(" __inlined %d (%d bytes)", ilt->count_inlines(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 ilt->count_inline_bcs());
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2142
a61af66fc99e Initial load
duke
parents:
diff changeset
2143
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 //------------------------------dump-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // Dump information associated with the bytecodes of current _method
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 void Parse::dump() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 if( method() != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 // Iterate over bytecodes
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 ciBytecodeStream iter(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 for( Bytecodes::Code bc = iter.next(); bc != ciBytecodeStream::EOBC() ; bc = iter.next() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 dump_bci( iter.cur_bci() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2156
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 // Dump information associated with a byte code index, 'bci'
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 void Parse::dump_bci(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 // Output info on merge-points, cloning, and within _jsr..._ret
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // NYI
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 tty->print(" bci:%d", 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 #endif