Mercurial > hg > truffle
annotate src/share/vm/opto/machnode.cpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | 6729bbc1fcd6 |
children | 8c92982cbbc4 |
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 //------------------------------peephole--------------------------------------- | |
393 // Apply peephole rule(s) to this instruction | |
394 MachNode *MachNode::peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C ) { | |
395 return NULL; | |
396 } | |
397 | |
398 //------------------------------add_case_label--------------------------------- | |
399 // Adds the label for the case | |
400 void MachNode::add_case_label( int index_num, Label* blockLabel) { | |
401 ShouldNotCallThis(); | |
402 } | |
403 | |
404 //------------------------------method_set------------------------------------- | |
405 // Set the absolute address of a method | |
406 void MachNode::method_set( intptr_t addr ) { | |
407 ShouldNotCallThis(); | |
408 } | |
409 | |
410 //------------------------------rematerialize---------------------------------- | |
411 bool MachNode::rematerialize() const { | |
412 // Temps are always rematerializable | |
413 if (is_MachTemp()) return true; | |
414 | |
415 uint r = rule(); // Match rule | |
416 if( r < Matcher::_begin_rematerialize || | |
417 r >= Matcher::_end_rematerialize ) | |
418 return false; | |
419 | |
420 // For 2-address instructions, the input live range is also the output | |
421 // live range. Remateralizing does not make progress on the that live range. | |
422 if( two_adr() ) return false; | |
423 | |
424 // Check for rematerializing float constants, or not | |
425 if( !Matcher::rematerialize_float_constants ) { | |
426 int op = ideal_Opcode(); | |
427 if( op == Op_ConF || op == Op_ConD ) | |
428 return false; | |
429 } | |
430 | |
431 // Defining flags - can't spill these! Must remateralize. | |
432 if( ideal_reg() == Op_RegFlags ) | |
433 return true; | |
434 | |
435 // Stretching lots of inputs - don't do it. | |
436 if( req() > 2 ) | |
437 return false; | |
438 | |
439 // Don't remateralize somebody with bound inputs - it stretches a | |
440 // fixed register lifetime. | |
441 uint idx = oper_input_base(); | |
442 if( req() > idx ) { | |
443 const RegMask &rm = in_RegMask(idx); | |
444 if( rm.is_bound1() || rm.is_bound2() ) | |
445 return false; | |
446 } | |
447 | |
448 return true; | |
449 } | |
450 | |
451 #ifndef PRODUCT | |
452 //------------------------------dump_spec-------------------------------------- | |
453 // Print any per-operand special info | |
454 void MachNode::dump_spec(outputStream *st) const { | |
455 uint cnt = num_opnds(); | |
456 for( uint i=0; i<cnt; i++ ) | |
457 _opnds[i]->dump_spec(st); | |
458 const TypePtr *t = adr_type(); | |
459 if( t ) { | |
460 Compile* C = Compile::current(); | |
461 if( C->alias_type(t)->is_volatile() ) | |
462 st->print(" Volatile!"); | |
463 } | |
464 } | |
465 | |
466 //------------------------------dump_format------------------------------------ | |
467 // access to virtual | |
468 void MachNode::dump_format(PhaseRegAlloc *ra, outputStream *st) const { | |
469 format(ra, st); // access to virtual | |
470 } | |
471 #endif | |
472 | |
473 //============================================================================= | |
474 #ifndef PRODUCT | |
475 void MachTypeNode::dump_spec(outputStream *st) const { | |
476 _bottom_type->dump_on(st); | |
477 } | |
478 #endif | |
479 | |
2008 | 480 |
481 //============================================================================= | |
482 int MachConstantNode::constant_offset() { | |
483 // Bind the offset lazily. | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
484 if (_constant.offset() == -1) { |
2008 | 485 Compile::ConstantTable& constant_table = Compile::current()->constant_table(); |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
486 int offset = constant_table.find_offset(_constant); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
487 // If called from Compile::scratch_emit_size return the |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
488 // pre-calculated offset. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
489 // NOTE: If the AD file does some table base offset optimizations |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
490 // later the AD file needs to take care of this fact. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
491 if (Compile::current()->in_scratch_emit_size()) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
492 return constant_table.calculate_table_base_offset() + offset; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
493 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
494 _constant.set_offset(constant_table.table_base_offset() + offset); |
2008 | 495 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4053
diff
changeset
|
496 return _constant.offset(); |
2008 | 497 } |
498 | |
499 | |
0 | 500 //============================================================================= |
501 #ifndef PRODUCT | |
502 void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { | |
503 int reg = ra_->get_reg_first(in(1)->in(_vidx)); | |
504 tty->print("%s %s", Name(), Matcher::regName[reg]); | |
505 } | |
506 #endif | |
507 | |
508 void MachNullCheckNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | |
509 // only emits entries in the null-pointer exception handler table | |
510 } | |
3839 | 511 void MachNullCheckNode::label_set(Label* label, uint block_num) { |
512 // Nothing to emit | |
513 } | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
514 void MachNullCheckNode::save_label( Label** label, uint* block_num ) { |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
515 // Nothing to emit |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
516 } |
0 | 517 |
518 const RegMask &MachNullCheckNode::in_RegMask( uint idx ) const { | |
519 if( idx == 0 ) return RegMask::Empty; | |
520 else return in(1)->as_Mach()->out_RegMask(); | |
521 } | |
522 | |
523 //============================================================================= | |
524 const Type *MachProjNode::bottom_type() const { | |
525 if( _ideal_reg == fat_proj ) return Type::BOTTOM; | |
526 // Try the normal mechanism first | |
527 const Type *t = in(0)->bottom_type(); | |
528 if( t->base() == Type::Tuple ) { | |
529 const TypeTuple *tt = t->is_tuple(); | |
530 if (_con < tt->cnt()) | |
531 return tt->field_at(_con); | |
532 } | |
533 // Else use generic type from ideal register set | |
534 assert((uint)_ideal_reg < (uint)_last_machine_leaf && Type::mreg2type[_ideal_reg], "in bounds"); | |
535 return Type::mreg2type[_ideal_reg]; | |
536 } | |
537 | |
538 const TypePtr *MachProjNode::adr_type() const { | |
539 if (bottom_type() == Type::MEMORY) { | |
540 // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM | |
541 const TypePtr* adr_type = in(0)->adr_type(); | |
542 #ifdef ASSERT | |
543 if (!is_error_reported() && !Node::in_dump()) | |
544 assert(adr_type != NULL, "source must have adr_type"); | |
545 #endif | |
546 return adr_type; | |
547 } | |
548 assert(bottom_type()->base() != Type::Memory, "no other memories?"); | |
549 return NULL; | |
550 } | |
551 | |
552 #ifndef PRODUCT | |
553 void MachProjNode::dump_spec(outputStream *st) const { | |
554 ProjNode::dump_spec(st); | |
555 switch (_ideal_reg) { | |
556 case unmatched_proj: st->print("/unmatched"); break; | |
557 case fat_proj: st->print("/fat"); if (WizardMode) _rout.dump(); break; | |
558 } | |
559 } | |
560 #endif | |
561 | |
562 //============================================================================= | |
563 #ifndef PRODUCT | |
564 void MachIfNode::dump_spec(outputStream *st) const { | |
565 st->print("P=%f, C=%f",_prob, _fcnt); | |
566 } | |
567 #endif | |
568 | |
569 //============================================================================= | |
570 uint MachReturnNode::size_of() const { return sizeof(*this); } | |
571 | |
572 //------------------------------Registers-------------------------------------- | |
573 const RegMask &MachReturnNode::in_RegMask( uint idx ) const { | |
574 return _in_rms[idx]; | |
575 } | |
576 | |
577 const TypePtr *MachReturnNode::adr_type() const { | |
578 // most returns and calls are assumed to consume & modify all of memory | |
579 // the matcher will copy non-wide adr_types from ideal originals | |
580 return _adr_type; | |
581 } | |
582 | |
583 //============================================================================= | |
584 const Type *MachSafePointNode::bottom_type() const { return TypeTuple::MEMBAR; } | |
585 | |
586 //------------------------------Registers-------------------------------------- | |
587 const RegMask &MachSafePointNode::in_RegMask( uint idx ) const { | |
588 // Values in the domain use the users calling convention, embodied in the | |
589 // _in_rms array of RegMasks. | |
590 if( idx < TypeFunc::Parms ) return _in_rms[idx]; | |
591 | |
592 if (SafePointNode::needs_polling_address_input() && | |
593 idx == TypeFunc::Parms && | |
594 ideal_Opcode() == Op_SafePoint) { | |
595 return MachNode::in_RegMask(idx); | |
596 } | |
597 | |
598 // Values outside the domain represent debug info | |
599 return *Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]; | |
600 } | |
601 | |
602 | |
603 //============================================================================= | |
604 | |
605 uint MachCallNode::cmp( const Node &n ) const | |
606 { return _tf == ((MachCallNode&)n)._tf; } | |
607 const Type *MachCallNode::bottom_type() const { return tf()->range(); } | |
608 const Type *MachCallNode::Value(PhaseTransform *phase) const { return tf()->range(); } | |
609 | |
610 #ifndef PRODUCT | |
611 void MachCallNode::dump_spec(outputStream *st) const { | |
612 st->print("# "); | |
613 tf()->dump_on(st); | |
614 if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); | |
615 if (jvms() != NULL) jvms()->dump_spec(st); | |
616 } | |
617 #endif | |
618 | |
619 | |
620 bool MachCallNode::return_value_is_used() const { | |
621 if (tf()->range()->cnt() == TypeFunc::Parms) { | |
622 // void return | |
623 return false; | |
624 } | |
625 | |
626 // find the projection corresponding to the return value | |
627 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { | |
628 Node *use = fast_out(i); | |
629 if (!use->is_Proj()) continue; | |
630 if (use->as_Proj()->_con == TypeFunc::Parms) { | |
631 return true; | |
632 } | |
633 } | |
634 return false; | |
635 } | |
636 | |
637 | |
638 //------------------------------Registers-------------------------------------- | |
639 const RegMask &MachCallNode::in_RegMask( uint idx ) const { | |
640 // Values in the domain use the users calling convention, embodied in the | |
641 // _in_rms array of RegMasks. | |
642 if (idx < tf()->domain()->cnt()) return _in_rms[idx]; | |
643 // Values outside the domain represent debug info | |
644 return *Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]; | |
645 } | |
646 | |
647 //============================================================================= | |
648 uint MachCallJavaNode::size_of() const { return sizeof(*this); } | |
649 uint MachCallJavaNode::cmp( const Node &n ) const { | |
650 MachCallJavaNode &call = (MachCallJavaNode&)n; | |
651 return MachCallNode::cmp(call) && _method->equals(call._method); | |
652 } | |
653 #ifndef PRODUCT | |
654 void MachCallJavaNode::dump_spec(outputStream *st) const { | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
655 if (_method_handle_invoke) |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
656 st->print("MethodHandle "); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
657 if (_method) { |
0 | 658 _method->print_short_name(st); |
659 st->print(" "); | |
660 } | |
661 MachCallNode::dump_spec(st); | |
662 } | |
663 #endif | |
664 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
665 //------------------------------Registers-------------------------------------- |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
666 const RegMask &MachCallJavaNode::in_RegMask(uint idx) const { |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
667 // 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
|
668 // _in_rms array of RegMasks. |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
669 if (idx < tf()->domain()->cnt()) return _in_rms[idx]; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
670 // Values outside the domain represent debug info |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
671 Matcher* m = Compile::current()->matcher(); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
672 // 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
|
673 // 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
|
674 // SP over MH invokes. |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
675 RegMask** debugmask = _method_handle_invoke ? m->idealreg2mhdebugmask : m->idealreg2debugmask; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
676 return *debugmask[in(idx)->ideal_reg()]; |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
677 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
866
diff
changeset
|
678 |
0 | 679 //============================================================================= |
680 uint MachCallStaticJavaNode::size_of() const { return sizeof(*this); } | |
681 uint MachCallStaticJavaNode::cmp( const Node &n ) const { | |
682 MachCallStaticJavaNode &call = (MachCallStaticJavaNode&)n; | |
683 return MachCallJavaNode::cmp(call) && _name == call._name; | |
684 } | |
685 | |
686 //----------------------------uncommon_trap_request---------------------------- | |
687 // If this is an uncommon trap, return the request code, else zero. | |
688 int MachCallStaticJavaNode::uncommon_trap_request() const { | |
689 if (_name != NULL && !strcmp(_name, "uncommon_trap")) { | |
690 return CallStaticJavaNode::extract_uncommon_trap_request(this); | |
691 } | |
692 return 0; | |
693 } | |
694 | |
695 #ifndef PRODUCT | |
696 // Helper for summarizing uncommon_trap arguments. | |
697 void MachCallStaticJavaNode::dump_trap_args(outputStream *st) const { | |
698 int trap_req = uncommon_trap_request(); | |
699 if (trap_req != 0) { | |
700 char buf[100]; | |
701 st->print("(%s)", | |
702 Deoptimization::format_trap_request(buf, sizeof(buf), | |
703 trap_req)); | |
704 } | |
705 } | |
706 | |
707 void MachCallStaticJavaNode::dump_spec(outputStream *st) const { | |
708 st->print("Static "); | |
709 if (_name != NULL) { | |
710 st->print("wrapper for: %s", _name ); | |
711 dump_trap_args(st); | |
712 st->print(" "); | |
713 } | |
714 MachCallJavaNode::dump_spec(st); | |
715 } | |
716 #endif | |
717 | |
718 //============================================================================= | |
719 #ifndef PRODUCT | |
720 void MachCallDynamicJavaNode::dump_spec(outputStream *st) const { | |
721 st->print("Dynamic "); | |
722 MachCallJavaNode::dump_spec(st); | |
723 } | |
724 #endif | |
725 //============================================================================= | |
726 uint MachCallRuntimeNode::size_of() const { return sizeof(*this); } | |
727 uint MachCallRuntimeNode::cmp( const Node &n ) const { | |
728 MachCallRuntimeNode &call = (MachCallRuntimeNode&)n; | |
729 return MachCallNode::cmp(call) && !strcmp(_name,call._name); | |
730 } | |
731 #ifndef PRODUCT | |
732 void MachCallRuntimeNode::dump_spec(outputStream *st) const { | |
733 st->print("%s ",_name); | |
734 MachCallNode::dump_spec(st); | |
735 } | |
736 #endif | |
737 //============================================================================= | |
738 // A shared JVMState for all HaltNodes. Indicates the start of debug info | |
739 // is at TypeFunc::Parms. Only required for SOE register spill handling - | |
740 // to indicate where the stack-slot-only debug info inputs begin. | |
741 // There is no other JVM state needed here. | |
742 JVMState jvms_for_throw(0); | |
743 JVMState *MachHaltNode::jvms() const { | |
744 return &jvms_for_throw; | |
745 } | |
746 | |
747 //============================================================================= | |
748 #ifndef PRODUCT | |
749 void labelOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const { | |
750 st->print("B%d", _block_num); | |
751 } | |
752 #endif // PRODUCT | |
753 | |
754 //============================================================================= | |
755 #ifndef PRODUCT | |
756 void methodOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const { | |
757 st->print(INTPTR_FORMAT, _method); | |
758 } | |
759 #endif // PRODUCT |