Mercurial > hg > truffle
annotate src/share/vm/opto/machnode.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 2f644f85485d |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1137
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1137
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1137
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_interface/collectedHeap.hpp" | |
27 #include "opto/machnode.hpp" | |
28 #include "opto/regalloc.hpp" | |
0 | 29 |
30 //============================================================================= | |
31 // Return the value requested | |
32 // result register lookup, corresponding to int_format | |
33 int MachOper::reg(PhaseRegAlloc *ra_, const Node *node) const { | |
34 return (int)ra_->get_encode(node); | |
35 } | |
36 // input register lookup, corresponding to ext_format | |
37 int MachOper::reg(PhaseRegAlloc *ra_, const Node *node, int idx) const { | |
38 return (int)(ra_->get_encode(node->in(idx))); | |
39 } | |
40 intptr_t MachOper::constant() const { return 0x00; } | |
41 bool MachOper::constant_is_oop() const { return false; } | |
42 jdouble MachOper::constantD() const { ShouldNotReachHere(); return 0.0; } | |
43 jfloat MachOper::constantF() const { ShouldNotReachHere(); return 0.0; } | |
44 jlong MachOper::constantL() const { ShouldNotReachHere(); return CONST64(0) ; } | |
45 TypeOopPtr *MachOper::oop() const { return NULL; } | |
46 int MachOper::ccode() const { return 0x00; } | |
47 // A zero, default, indicates this value is not needed. | |
48 // May need to lookup the base register, as done in int_ and ext_format | |
49 int MachOper::base (PhaseRegAlloc *ra_, const Node *node, int idx) const { return 0x00; } | |
50 int MachOper::index(PhaseRegAlloc *ra_, const Node *node, int idx) const { return 0x00; } | |
51 int MachOper::scale() const { return 0x00; } | |
52 int MachOper::disp (PhaseRegAlloc *ra_, const Node *node, int idx) const { return 0x00; } | |
53 int MachOper::constant_disp() const { return 0; } | |
54 int MachOper::base_position() const { return -1; } // no base input | |
55 int MachOper::index_position() const { return -1; } // no index input | |
56 // Check for PC-Relative displacement | |
57 bool MachOper::disp_is_oop() const { return false; } | |
58 // Return the label | |
59 Label* MachOper::label() const { ShouldNotReachHere(); return 0; } | |
60 intptr_t MachOper::method() const { ShouldNotReachHere(); return 0; } | |
61 | |
62 | |
63 //------------------------------negate----------------------------------------- | |
64 // Negate conditional branches. Error for non-branch operands | |
65 void MachOper::negate() { | |
66 ShouldNotCallThis(); | |
67 } | |
68 | |
69 //-----------------------------type-------------------------------------------- | |
70 const Type *MachOper::type() const { | |
71 return Type::BOTTOM; | |
72 } | |
73 | |
74 //------------------------------in_RegMask------------------------------------- | |
75 const RegMask *MachOper::in_RegMask(int index) const { | |
76 ShouldNotReachHere(); | |
77 return NULL; | |
78 } | |
79 | |
80 //------------------------------dump_spec-------------------------------------- | |
81 // Print any per-operand special info | |
82 #ifndef PRODUCT | |
83 void MachOper::dump_spec(outputStream *st) const { } | |
84 #endif | |
85 | |
86 //------------------------------hash------------------------------------------- | |
87 // Print any per-operand special info | |
88 uint MachOper::hash() const { | |
89 ShouldNotCallThis(); | |
90 return 5; | |
91 } | |
92 | |
93 //------------------------------cmp-------------------------------------------- | |
94 // Print any per-operand special info | |
95 uint MachOper::cmp( const MachOper &oper ) const { | |
96 ShouldNotCallThis(); | |
97 return opcode() == oper.opcode(); | |
98 } | |
99 | |
100 //------------------------------hash------------------------------------------- | |
101 // Print any per-operand special info | |
102 uint labelOper::hash() const { | |
103 return _block_num; | |
104 } | |
105 | |
106 //------------------------------cmp-------------------------------------------- | |
107 // Print any per-operand special info | |
108 uint labelOper::cmp( const MachOper &oper ) const { | |
109 return (opcode() == oper.opcode()) && (_label == oper.label()); | |
110 } | |
111 | |
112 //------------------------------hash------------------------------------------- | |
113 // Print any per-operand special info | |
114 uint methodOper::hash() const { | |
115 return (uint)_method; | |
116 } | |
117 | |
118 //------------------------------cmp-------------------------------------------- | |
119 // Print any per-operand special info | |
120 uint methodOper::cmp( const MachOper &oper ) const { | |
121 return (opcode() == oper.opcode()) && (_method == oper.method()); | |
122 } | |
123 | |
124 | |
125 //============================================================================= | |
126 //------------------------------MachNode--------------------------------------- | |
127 | |
128 //------------------------------emit------------------------------------------- | |
129 void MachNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
130 #ifdef ASSERT | |
131 tty->print("missing MachNode emit function: "); | |
132 dump(); | |
133 #endif | |
134 ShouldNotCallThis(); | |
135 } | |
136 | |
137 //------------------------------size------------------------------------------- | |
138 // Size of instruction in bytes | |
139 uint MachNode::size(PhaseRegAlloc *ra_) const { | |
140 // If a virtual was not defined for this specific instruction, | |
605 | 141 // Call the helper which finds the size by emitting the bits. |
0 | 142 return MachNode::emit_size(ra_); |
143 } | |
144 | |
145 //------------------------------size------------------------------------------- | |
146 // Helper function that computes size by emitting code | |
147 uint MachNode::emit_size(PhaseRegAlloc *ra_) const { | |
148 // Emit into a trash buffer and count bytes emitted. | |
149 assert(ra_ == ra_->C->regalloc(), "sanity"); | |
150 return ra_->C->scratch_emit_size(this); | |
151 } | |
152 | |
153 | |
154 | |
155 //------------------------------hash------------------------------------------- | |
156 uint MachNode::hash() const { | |
157 uint no = num_opnds(); | |
158 uint sum = rule(); | |
159 for( uint i=0; i<no; i++ ) | |
160 sum += _opnds[i]->hash(); | |
161 return sum+Node::hash(); | |
162 } | |
163 | |
164 //-----------------------------cmp--------------------------------------------- | |
165 uint MachNode::cmp( const Node &node ) const { | |
166 MachNode& n = *((Node&)node).as_Mach(); | |
167 uint no = num_opnds(); | |
168 if( no != n.num_opnds() ) return 0; | |
169 if( rule() != n.rule() ) return 0; | |
170 for( uint i=0; i<no; i++ ) // All operands must match | |
171 if( !_opnds[i]->cmp( *n._opnds[i] ) ) | |
172 return 0; // mis-matched operands | |
173 return 1; // match | |
174 } | |
175 | |
176 // Return an equivalent instruction using memory for cisc_operand position | |
177 MachNode *MachNode::cisc_version(int offset, Compile* C) { | |
178 ShouldNotCallThis(); | |
179 return NULL; | |
180 } | |
181 | |
182 void MachNode::use_cisc_RegMask() { | |
183 ShouldNotReachHere(); | |
184 } | |
185 | |
186 | |
187 //-----------------------------in_RegMask-------------------------------------- | |
188 const RegMask &MachNode::in_RegMask( uint idx ) const { | |
189 uint numopnds = num_opnds(); // Virtual call for number of operands | |
190 uint skipped = oper_input_base(); // Sum of leaves skipped so far | |
191 if( idx < skipped ) { | |
192 assert( ideal_Opcode() == Op_AddP, "expected base ptr here" ); | |
193 assert( idx == 1, "expected base ptr here" ); | |
194 // debug info can be anywhere | |
195 return *Compile::current()->matcher()->idealreg2spillmask[Op_RegP]; | |
196 } | |
197 uint opcnt = 1; // First operand | |
198 uint num_edges = _opnds[1]->num_edges(); // leaves for first operand | |
199 while( idx >= skipped+num_edges ) { | |
200 skipped += num_edges; | |
201 opcnt++; // Bump operand count | |
202 assert( opcnt < numopnds, "Accessing non-existent operand" ); | |
203 num_edges = _opnds[opcnt]->num_edges(); // leaves for next operand | |
204 } | |
205 | |
206 const RegMask *rm = cisc_RegMask(); | |
207 if( rm == NULL || (int)opcnt != cisc_operand() ) { | |
208 rm = _opnds[opcnt]->in_RegMask(idx-skipped); | |
209 } | |
210 return *rm; | |
211 } | |
212 | |
213 //-----------------------------memory_inputs-------------------------------- | |
214 const MachOper* MachNode::memory_inputs(Node* &base, Node* &index) const { | |
215 const MachOper* oper = memory_operand(); | |
216 | |
217 if (oper == (MachOper*)-1) { | |
218 base = NodeSentinel; | |
219 index = NodeSentinel; | |
220 } else { | |
221 base = NULL; | |
222 index = NULL; | |
223 if (oper != NULL) { | |
224 // It has a unique memory operand. Find its index. | |
225 int oper_idx = num_opnds(); | |
226 while (--oper_idx >= 0) { | |
227 if (_opnds[oper_idx] == oper) break; | |
228 } | |
229 int oper_pos = operand_index(oper_idx); | |
230 int base_pos = oper->base_position(); | |
231 if (base_pos >= 0) { | |
232 base = _in[oper_pos+base_pos]; | |
233 } | |
234 int index_pos = oper->index_position(); | |
235 if (index_pos >= 0) { | |
236 index = _in[oper_pos+index_pos]; | |
237 } | |
238 } | |
239 } | |
240 | |
241 return oper; | |
242 } | |
243 | |
244 //-----------------------------get_base_and_disp---------------------------- | |
245 const Node* MachNode::get_base_and_disp(intptr_t &offset, const TypePtr* &adr_type) const { | |
246 | |
247 // Find the memory inputs using our helper function | |
248 Node* base; | |
249 Node* index; | |
250 const MachOper* oper = memory_inputs(base, index); | |
251 | |
252 if (oper == NULL) { | |
253 // Base has been set to NULL | |
254 offset = 0; | |
255 } else if (oper == (MachOper*)-1) { | |
256 // Base has been set to NodeSentinel | |
257 // There is not a unique memory use here. We will fall to AliasIdxBot. | |
258 offset = Type::OffsetBot; | |
259 } else { | |
260 // Base may be NULL, even if offset turns out to be != 0 | |
261 | |
262 intptr_t disp = oper->constant_disp(); | |
263 int scale = oper->scale(); | |
264 // Now we have collected every part of the ADLC MEMORY_INTER. | |
265 // See if it adds up to a base + offset. | |
266 if (index != NULL) { | |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
267 const Type* t_index = index->bottom_type(); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
268 if (t_index->isa_narrowoop()) { // EncodeN, LoadN, LoadConN, LoadNKlass. |
216
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
269 // Memory references through narrow oops have a |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
270 // funny base so grab the type from the index: |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
271 // [R12 + narrow_oop_reg<<3 + offset] |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
272 assert(base == NULL, "Memory references through narrow oops have no base"); |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
273 offset = disp; |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
274 adr_type = t_index->make_ptr()->add_offset(offset); |
216
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
275 return NULL; |
8d191a7697e2
6715633: when matching a memory node the adr_type should not change
kvn
parents:
113
diff
changeset
|
276 } else if (!index->is_Con()) { |
0 | 277 disp = Type::OffsetBot; |
278 } else if (disp != Type::OffsetBot) { | |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
216
diff
changeset
|
279 const TypeX* ti = t_index->isa_intptr_t(); |
0 | 280 if (ti == NULL) { |
281 disp = Type::OffsetBot; // a random constant?? | |
282 } else { | |
283 disp += ti->get_con() << scale; | |
284 } | |
285 } | |
286 } | |
287 offset = disp; | |
288 | |
289 // In i486.ad, indOffset32X uses base==RegI and disp==RegP, | |
290 // this will prevent alias analysis without the following support: | |
291 // Lookup the TypePtr used by indOffset32X, a compile-time constant oop, | |
292 // Add the offset determined by the "base", or use Type::OffsetBot. | |
293 if( adr_type == TYPE_PTR_SENTINAL ) { | |
294 const TypePtr *t_disp = oper->disp_as_type(); // only !NULL for indOffset32X | |
295 if (t_disp != NULL) { | |
296 offset = Type::OffsetBot; | |
297 const Type* t_base = base->bottom_type(); | |
298 if (t_base->isa_intptr_t()) { | |
299 const TypeX *t_offset = t_base->is_intptr_t(); | |
300 if( t_offset->is_con() ) { | |
301 offset = t_offset->get_con(); | |
302 } | |
303 } | |
304 adr_type = t_disp->add_offset(offset); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
673
diff
changeset
|
305 } else if( base == NULL && offset != 0 && offset != Type::OffsetBot ) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
673
diff
changeset
|
306 // Use ideal type if it is oop ptr. |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
673
diff
changeset
|
307 const TypePtr *tp = oper->type()->isa_ptr(); |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
673
diff
changeset
|
308 if( tp != NULL) { |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
673
diff
changeset
|
309 adr_type = tp; |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
673
diff
changeset
|
310 } |
0 | 311 } |
312 } | |
313 | |
314 } | |
315 return base; | |
316 } | |
317 | |
318 | |
319 //---------------------------------adr_type--------------------------------- | |
320 const class TypePtr *MachNode::adr_type() const { | |
321 intptr_t offset = 0; | |
322 const TypePtr *adr_type = TYPE_PTR_SENTINAL; // attempt computing adr_type | |
323 const Node *base = get_base_and_disp(offset, adr_type); | |
324 if( adr_type != TYPE_PTR_SENTINAL ) { | |
325 return adr_type; // get_base_and_disp has the answer | |
326 } | |
327 | |
328 // Direct addressing modes have no base node, simply an indirect | |
329 // offset, which is always to raw memory. | |
330 // %%%%% Someday we'd like to allow constant oop offsets which | |
331 // would let Intel load from static globals in 1 instruction. | |
332 // Currently Intel requires 2 instructions and a register temp. | |
333 if (base == NULL) { | |
334 // NULL base, zero offset means no memory at all (a null pointer!) | |
335 if (offset == 0) { | |
336 return NULL; | |
337 } | |
338 // NULL base, any offset means any pointer whatever | |
339 if (offset == Type::OffsetBot) { | |
340 return TypePtr::BOTTOM; | |
341 } | |
342 // %%% make offset be intptr_t | |
343 assert(!Universe::heap()->is_in_reserved((oop)offset), "must be a raw ptr"); | |
344 return TypeRawPtr::BOTTOM; | |
345 } | |
346 | |
347 // base of -1 with no particular offset means all of memory | |
348 if (base == NodeSentinel) return TypePtr::BOTTOM; | |
349 | |
350 const Type* t = base->bottom_type(); | |
673 | 351 if (UseCompressedOops && Universe::narrow_oop_shift() == 0) { |
352 // 32-bit unscaled narrow oop can be the base of any address expression | |
353 t = t->make_ptr(); | |
354 } | |
0 | 355 if (t->isa_intptr_t() && offset != 0 && offset != Type::OffsetBot) { |
356 // We cannot assert that the offset does not look oop-ish here. | |
357 // Depending on the heap layout the cardmark base could land | |
358 // inside some oopish region. It definitely does for Win2K. | |
359 // The sum of cardmark-base plus shift-by-9-oop lands outside | |
360 // the oop-ish area but we can't assert for that statically. | |
361 return TypeRawPtr::BOTTOM; | |
362 } | |
363 | |
364 const TypePtr *tp = t->isa_ptr(); | |
365 | |
366 // be conservative if we do not recognize the type | |
367 if (tp == NULL) { | |
673 | 368 assert(false, "this path may produce not optimal code"); |
0 | 369 return TypePtr::BOTTOM; |
370 } | |
371 assert(tp->base() != Type::AnyPtr, "not a bare pointer"); | |
372 | |
373 return tp->add_offset(offset); | |
374 } | |
375 | |
376 | |
377 //-----------------------------operand_index--------------------------------- | |
378 int MachNode::operand_index( uint operand ) const { | |
379 if( operand < 1 ) return -1; | |
380 assert(operand < num_opnds(), "oob"); | |
381 if( _opnds[operand]->num_edges() == 0 ) return -1; | |
382 | |
383 uint skipped = oper_input_base(); // Sum of leaves skipped so far | |
384 for (uint opcnt = 1; opcnt < operand; opcnt++) { | |
385 uint num_edges = _opnds[opcnt]->num_edges(); // leaves for operand | |
386 skipped += num_edges; | |
387 } | |
388 return skipped; | |
389 } | |
390 | |
391 | |
392 //------------------------------negate----------------------------------------- | |
393 // Negate conditional branches. Error for non-branch Nodes | |
394 void MachNode::negate() { | |
395 ShouldNotCallThis(); | |
396 } | |
397 | |
398 //------------------------------peephole--------------------------------------- | |
399 // Apply peephole rule(s) to this instruction | |
400 MachNode *MachNode::peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C ) { | |
401 return NULL; | |
402 } | |
403 | |
404 //------------------------------add_case_label--------------------------------- | |
405 // Adds the label for the case | |
406 void MachNode::add_case_label( int index_num, Label* blockLabel) { | |
407 ShouldNotCallThis(); | |
408 } | |
409 | |
410 //------------------------------label_set-------------------------------------- | |
411 // Set the Label for a LabelOper, if an operand for this instruction | |
412 void MachNode::label_set( Label& label, uint block_num ) { | |
413 ShouldNotCallThis(); | |
414 } | |
415 | |
416 //------------------------------method_set------------------------------------- | |
417 // Set the absolute address of a method | |
418 void MachNode::method_set( intptr_t addr ) { | |
419 ShouldNotCallThis(); | |
420 } | |
421 | |
422 //------------------------------rematerialize---------------------------------- | |
423 bool MachNode::rematerialize() const { | |
424 // Temps are always rematerializable | |
425 if (is_MachTemp()) return true; | |
426 | |
427 uint r = rule(); // Match rule | |
428 if( r < Matcher::_begin_rematerialize || | |
429 r >= Matcher::_end_rematerialize ) | |
430 return false; | |
431 | |
432 // For 2-address instructions, the input live range is also the output | |
433 // live range. Remateralizing does not make progress on the that live range. | |
434 if( two_adr() ) return false; | |
435 | |
436 // Check for rematerializing float constants, or not | |
437 if( !Matcher::rematerialize_float_constants ) { | |
438 int op = ideal_Opcode(); | |
439 if( op == Op_ConF || op == Op_ConD ) | |
440 return false; | |
441 } | |
442 | |
443 // Defining flags - can't spill these! Must remateralize. | |
444 if( ideal_reg() == Op_RegFlags ) | |
445 return true; | |
446 | |
447 // Stretching lots of inputs - don't do it. | |
448 if( req() > 2 ) | |
449 return false; | |
450 | |
451 // Don't remateralize somebody with bound inputs - it stretches a | |
452 // fixed register lifetime. | |
453 uint idx = oper_input_base(); | |
454 if( req() > idx ) { | |
455 const RegMask &rm = in_RegMask(idx); | |
456 if( rm.is_bound1() || rm.is_bound2() ) | |
457 return false; | |
458 } | |
459 | |
460 return true; | |
461 } | |
462 | |
463 #ifndef PRODUCT | |
464 //------------------------------dump_spec-------------------------------------- | |
465 // Print any per-operand special info | |
466 void MachNode::dump_spec(outputStream *st) const { | |
467 uint cnt = num_opnds(); | |
468 for( uint i=0; i<cnt; i++ ) | |
469 _opnds[i]->dump_spec(st); | |
470 const TypePtr *t = adr_type(); | |
471 if( t ) { | |
472 Compile* C = Compile::current(); | |
473 if( C->alias_type(t)->is_volatile() ) | |
474 st->print(" Volatile!"); | |
475 } | |
476 } | |
477 | |
478 //------------------------------dump_format------------------------------------ | |
479 // access to virtual | |
480 void MachNode::dump_format(PhaseRegAlloc *ra, outputStream *st) const { | |
481 format(ra, st); // access to virtual | |
482 } | |
483 #endif | |
484 | |
485 //============================================================================= | |
486 #ifndef PRODUCT | |
487 void MachTypeNode::dump_spec(outputStream *st) const { | |
488 _bottom_type->dump_on(st); | |
489 } | |
490 #endif | |
491 | |
492 //============================================================================= | |
493 #ifndef PRODUCT | |
494 void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
495 int reg = ra_->get_reg_first(in(1)->in(_vidx)); | |
496 tty->print("%s %s", Name(), Matcher::regName[reg]); | |
497 } | |
498 #endif | |
499 | |
500 void MachNullCheckNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
501 // only emits entries in the null-pointer exception handler table | |
502 } | |
503 | |
504 const RegMask &MachNullCheckNode::in_RegMask( uint idx ) const { | |
505 if( idx == 0 ) return RegMask::Empty; | |
506 else return in(1)->as_Mach()->out_RegMask(); | |
507 } | |
508 | |
509 //============================================================================= | |
510 const Type *MachProjNode::bottom_type() const { | |
511 if( _ideal_reg == fat_proj ) return Type::BOTTOM; | |
512 // Try the normal mechanism first | |
513 const Type *t = in(0)->bottom_type(); | |
514 if( t->base() == Type::Tuple ) { | |
515 const TypeTuple *tt = t->is_tuple(); | |
516 if (_con < tt->cnt()) | |
517 return tt->field_at(_con); | |
518 } | |
519 // Else use generic type from ideal register set | |
520 assert((uint)_ideal_reg < (uint)_last_machine_leaf && Type::mreg2type[_ideal_reg], "in bounds"); | |
521 return Type::mreg2type[_ideal_reg]; | |
522 } | |
523 | |
524 const TypePtr *MachProjNode::adr_type() const { | |
525 if (bottom_type() == Type::MEMORY) { | |
526 // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM | |
527 const TypePtr* adr_type = in(0)->adr_type(); | |
528 #ifdef ASSERT | |
529 if (!is_error_reported() && !Node::in_dump()) | |
530 assert(adr_type != NULL, "source must have adr_type"); | |
531 #endif | |
532 return adr_type; | |
533 } | |
534 assert(bottom_type()->base() != Type::Memory, "no other memories?"); | |
535 return NULL; | |
536 } | |
537 | |
538 #ifndef PRODUCT | |
539 void MachProjNode::dump_spec(outputStream *st) const { | |
540 ProjNode::dump_spec(st); | |
541 switch (_ideal_reg) { | |
542 case unmatched_proj: st->print("/unmatched"); break; | |
543 case fat_proj: st->print("/fat"); if (WizardMode) _rout.dump(); break; | |
544 } | |
545 } | |
546 #endif | |
547 | |
548 //============================================================================= | |
549 #ifndef PRODUCT | |
550 void MachIfNode::dump_spec(outputStream *st) const { | |
551 st->print("P=%f, C=%f",_prob, _fcnt); | |
552 } | |
553 #endif | |
554 | |
555 //============================================================================= | |
556 uint MachReturnNode::size_of() const { return sizeof(*this); } | |
557 | |
558 //------------------------------Registers-------------------------------------- | |
559 const RegMask &MachReturnNode::in_RegMask( uint idx ) const { | |
560 return _in_rms[idx]; | |
561 } | |
562 | |
563 const TypePtr *MachReturnNode::adr_type() const { | |
564 // most returns and calls are assumed to consume & modify all of memory | |
565 // the matcher will copy non-wide adr_types from ideal originals | |
566 return _adr_type; | |
567 } | |
568 | |
569 //============================================================================= | |
570 const Type *MachSafePointNode::bottom_type() const { return TypeTuple::MEMBAR; } | |
571 | |
572 //------------------------------Registers-------------------------------------- | |
573 const RegMask &MachSafePointNode::in_RegMask( uint idx ) const { | |
574 // Values in the domain use the users calling convention, embodied in the | |
575 // _in_rms array of RegMasks. | |
576 if( idx < TypeFunc::Parms ) return _in_rms[idx]; | |
577 | |
578 if (SafePointNode::needs_polling_address_input() && | |
579 idx == TypeFunc::Parms && | |
580 ideal_Opcode() == Op_SafePoint) { | |
581 return MachNode::in_RegMask(idx); | |
582 } | |
583 | |
584 // Values outside the domain represent debug info | |
585 return *Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]; | |
586 } | |
587 | |
588 | |
589 //============================================================================= | |
590 | |
591 uint MachCallNode::cmp( const Node &n ) const | |
592 { return _tf == ((MachCallNode&)n)._tf; } | |
593 const Type *MachCallNode::bottom_type() const { return tf()->range(); } | |
594 const Type *MachCallNode::Value(PhaseTransform *phase) const { return tf()->range(); } | |
595 | |
596 #ifndef PRODUCT | |
597 void MachCallNode::dump_spec(outputStream *st) const { | |
598 st->print("# "); | |
599 tf()->dump_on(st); | |
600 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); | |
601 if (jvms() != NULL) jvms()->dump_spec(st); | |
602 } | |
603 #endif | |
604 | |
605 | |
606 bool MachCallNode::return_value_is_used() const { | |
607 if (tf()->range()->cnt() == TypeFunc::Parms) { | |
608 // void return | |
609 return false; | |
610 } | |
611 | |
612 // find the projection corresponding to the return value | |
613 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { | |
614 Node *use = fast_out(i); | |
615 if (!use->is_Proj()) continue; | |
616 if (use->as_Proj()->_con == TypeFunc::Parms) { | |
617 return true; | |
618 } | |
619 } | |
620 return false; | |
621 } | |
622 | |
623 | |
624 //------------------------------Registers-------------------------------------- | |
625 const RegMask &MachCallNode::in_RegMask( uint idx ) const { | |
626 // Values in the domain use the users calling convention, embodied in the | |
627 // _in_rms array of RegMasks. | |
628 if (idx < tf()->domain()->cnt()) return _in_rms[idx]; | |
629 // Values outside the domain represent debug info | |
630 return *Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]; | |
631 } | |
632 | |
633 //============================================================================= | |
634 uint MachCallJavaNode::size_of() const { return sizeof(*this); } | |
635 uint MachCallJavaNode::cmp( const Node &n ) const { | |
636 MachCallJavaNode &call = (MachCallJavaNode&)n; | |
637 return MachCallNode::cmp(call) && _method->equals(call._method); | |
638 } | |
639 #ifndef PRODUCT | |
640 void MachCallJavaNode::dump_spec(outputStream *st) const { | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
641 if (_method_handle_invoke) |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
642 st->print("MethodHandle "); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
643 if (_method) { |
0 | 644 _method->print_short_name(st); |
645 st->print(" "); | |
646 } | |
647 MachCallNode::dump_spec(st); | |
648 } | |
649 #endif | |
650 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
651 //------------------------------Registers-------------------------------------- |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
652 const RegMask &MachCallJavaNode::in_RegMask(uint idx) const { |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
653 // Values in the domain use the users calling convention, embodied in the |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
654 // _in_rms array of RegMasks. |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
655 if (idx < tf()->domain()->cnt()) return _in_rms[idx]; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
656 // Values outside the domain represent debug info |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
657 Matcher* m = Compile::current()->matcher(); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
658 // If this call is a MethodHandle invoke we have to use a different |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
659 // debugmask which does not include the register we use to save the |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
660 // SP over MH invokes. |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
661 RegMask** debugmask = _method_handle_invoke ? m->idealreg2mhdebugmask : m->idealreg2debugmask; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
662 return *debugmask[in(idx)->ideal_reg()]; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
663 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
664 |
0 | 665 //============================================================================= |
666 uint MachCallStaticJavaNode::size_of() const { return sizeof(*this); } | |
667 uint MachCallStaticJavaNode::cmp( const Node &n ) const { | |
668 MachCallStaticJavaNode &call = (MachCallStaticJavaNode&)n; | |
669 return MachCallJavaNode::cmp(call) && _name == call._name; | |
670 } | |
671 | |
672 //----------------------------uncommon_trap_request---------------------------- | |
673 // If this is an uncommon trap, return the request code, else zero. | |
674 int MachCallStaticJavaNode::uncommon_trap_request() const { | |
675 if (_name != NULL && !strcmp(_name, "uncommon_trap")) { | |
676 return CallStaticJavaNode::extract_uncommon_trap_request(this); | |
677 } | |
678 return 0; | |
679 } | |
680 | |
681 #ifndef PRODUCT | |
682 // Helper for summarizing uncommon_trap arguments. | |
683 void MachCallStaticJavaNode::dump_trap_args(outputStream *st) const { | |
684 int trap_req = uncommon_trap_request(); | |
685 if (trap_req != 0) { | |
686 char buf[100]; | |
687 st->print("(%s)", | |
688 Deoptimization::format_trap_request(buf, sizeof(buf), | |
689 trap_req)); | |
690 } | |
691 } | |
692 | |
693 void MachCallStaticJavaNode::dump_spec(outputStream *st) const { | |
694 st->print("Static "); | |
695 if (_name != NULL) { | |
696 st->print("wrapper for: %s", _name ); | |
697 dump_trap_args(st); | |
698 st->print(" "); | |
699 } | |
700 MachCallJavaNode::dump_spec(st); | |
701 } | |
702 #endif | |
703 | |
704 //============================================================================= | |
705 #ifndef PRODUCT | |
706 void MachCallDynamicJavaNode::dump_spec(outputStream *st) const { | |
707 st->print("Dynamic "); | |
708 MachCallJavaNode::dump_spec(st); | |
709 } | |
710 #endif | |
711 //============================================================================= | |
712 uint MachCallRuntimeNode::size_of() const { return sizeof(*this); } | |
713 uint MachCallRuntimeNode::cmp( const Node &n ) const { | |
714 MachCallRuntimeNode &call = (MachCallRuntimeNode&)n; | |
715 return MachCallNode::cmp(call) && !strcmp(_name,call._name); | |
716 } | |
717 #ifndef PRODUCT | |
718 void MachCallRuntimeNode::dump_spec(outputStream *st) const { | |
719 st->print("%s ",_name); | |
720 MachCallNode::dump_spec(st); | |
721 } | |
722 #endif | |
723 //============================================================================= | |
724 // A shared JVMState for all HaltNodes. Indicates the start of debug info | |
725 // is at TypeFunc::Parms. Only required for SOE register spill handling - | |
726 // to indicate where the stack-slot-only debug info inputs begin. | |
727 // There is no other JVM state needed here. | |
728 JVMState jvms_for_throw(0); | |
729 JVMState *MachHaltNode::jvms() const { | |
730 return &jvms_for_throw; | |
731 } | |
732 | |
733 //============================================================================= | |
734 #ifndef PRODUCT | |
735 void labelOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const { | |
736 st->print("B%d", _block_num); | |
737 } | |
738 #endif // PRODUCT | |
739 | |
740 //============================================================================= | |
741 #ifndef PRODUCT | |
742 void methodOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const { | |
743 st->print(INTPTR_FORMAT, _method); | |
744 } | |
745 #endif // PRODUCT |