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