Mercurial > hg > truffle
annotate src/share/vm/c1/c1_LIRGenerator.hpp @ 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 | 126ea7725993 |
children | d5d065957597 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
diff
changeset
|
2 * Copyright (c) 2005, 2006, 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:
342
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
342
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:
342
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // The classes responsible for code emission and register allocation | |
26 | |
27 | |
28 class LIRGenerator; | |
29 class LIREmitter; | |
30 class Invoke; | |
31 class SwitchRange; | |
32 class LIRItem; | |
33 | |
34 define_array(LIRItemArray, LIRItem*) | |
35 define_stack(LIRItemList, LIRItemArray) | |
36 | |
37 class SwitchRange: public CompilationResourceObj { | |
38 private: | |
39 int _low_key; | |
40 int _high_key; | |
41 BlockBegin* _sux; | |
42 public: | |
43 SwitchRange(int start_key, BlockBegin* sux): _low_key(start_key), _high_key(start_key), _sux(sux) {} | |
44 void set_high_key(int key) { _high_key = key; } | |
45 | |
46 int high_key() const { return _high_key; } | |
47 int low_key() const { return _low_key; } | |
48 BlockBegin* sux() const { return _sux; } | |
49 }; | |
50 | |
51 define_array(SwitchRangeArray, SwitchRange*) | |
52 define_stack(SwitchRangeList, SwitchRangeArray) | |
53 | |
54 | |
55 class ResolveNode; | |
56 | |
57 define_array(NodeArray, ResolveNode*); | |
58 define_stack(NodeList, NodeArray); | |
59 | |
60 | |
61 // Node objects form a directed graph of LIR_Opr | |
62 // Edges between Nodes represent moves from one Node to its destinations | |
63 class ResolveNode: public CompilationResourceObj { | |
64 private: | |
65 LIR_Opr _operand; // the source or destinaton | |
66 NodeList _destinations; // for the operand | |
67 bool _assigned; // Value assigned to this Node? | |
68 bool _visited; // Node already visited? | |
69 bool _start_node; // Start node already visited? | |
70 | |
71 public: | |
72 ResolveNode(LIR_Opr operand) | |
73 : _operand(operand) | |
74 , _assigned(false) | |
75 , _visited(false) | |
76 , _start_node(false) {}; | |
77 | |
78 // accessors | |
79 LIR_Opr operand() const { return _operand; } | |
80 int no_of_destinations() const { return _destinations.length(); } | |
81 ResolveNode* destination_at(int i) { return _destinations[i]; } | |
82 bool assigned() const { return _assigned; } | |
83 bool visited() const { return _visited; } | |
84 bool start_node() const { return _start_node; } | |
85 | |
86 // modifiers | |
87 void append(ResolveNode* dest) { _destinations.append(dest); } | |
88 void set_assigned() { _assigned = true; } | |
89 void set_visited() { _visited = true; } | |
90 void set_start_node() { _start_node = true; } | |
91 }; | |
92 | |
93 | |
94 // This is shared state to be used by the PhiResolver so the operand | |
95 // arrays don't have to be reallocated for reach resolution. | |
96 class PhiResolverState: public CompilationResourceObj { | |
97 friend class PhiResolver; | |
98 | |
99 private: | |
100 NodeList _virtual_operands; // Nodes where the operand is a virtual register | |
101 NodeList _other_operands; // Nodes where the operand is not a virtual register | |
102 NodeList _vreg_table; // Mapping from virtual register to Node | |
103 | |
104 public: | |
105 PhiResolverState() {} | |
106 | |
107 void reset(int max_vregs); | |
108 }; | |
109 | |
110 | |
111 // class used to move value of phi operand to phi function | |
112 class PhiResolver: public CompilationResourceObj { | |
113 private: | |
114 LIRGenerator* _gen; | |
115 PhiResolverState& _state; // temporary state cached by LIRGenerator | |
116 | |
117 ResolveNode* _loop; | |
118 LIR_Opr _temp; | |
119 | |
120 // access to shared state arrays | |
121 NodeList& virtual_operands() { return _state._virtual_operands; } | |
122 NodeList& other_operands() { return _state._other_operands; } | |
123 NodeList& vreg_table() { return _state._vreg_table; } | |
124 | |
125 ResolveNode* create_node(LIR_Opr opr, bool source); | |
126 ResolveNode* source_node(LIR_Opr opr) { return create_node(opr, true); } | |
127 ResolveNode* destination_node(LIR_Opr opr) { return create_node(opr, false); } | |
128 | |
129 void emit_move(LIR_Opr src, LIR_Opr dest); | |
130 void move_to_temp(LIR_Opr src); | |
131 void move_temp_to(LIR_Opr dest); | |
132 void move(ResolveNode* src, ResolveNode* dest); | |
133 | |
134 LIRGenerator* gen() { | |
135 return _gen; | |
136 } | |
137 | |
138 public: | |
139 PhiResolver(LIRGenerator* _lir_gen, int max_vregs); | |
140 ~PhiResolver(); | |
141 | |
142 void move(LIR_Opr src, LIR_Opr dest); | |
143 }; | |
144 | |
145 | |
146 // only the classes below belong in the same file | |
147 class LIRGenerator: public InstructionVisitor, public BlockClosure { | |
342 | 148 |
0 | 149 private: |
150 Compilation* _compilation; | |
151 ciMethod* _method; // method that we are compiling | |
152 PhiResolverState _resolver_state; | |
153 BlockBegin* _block; | |
154 int _virtual_register_number; | |
155 Values _instruction_for_operand; | |
156 BitMap2D _vreg_flags; // flags which can be set on a per-vreg basis | |
157 LIR_List* _lir; | |
342 | 158 BarrierSet* _bs; |
0 | 159 |
160 LIRGenerator* gen() { | |
161 return this; | |
162 } | |
163 | |
164 #ifdef ASSERT | |
165 LIR_List* lir(const char * file, int line) const { | |
166 _lir->set_file_and_line(file, line); | |
167 return _lir; | |
168 } | |
169 #endif | |
170 LIR_List* lir() const { | |
171 return _lir; | |
172 } | |
173 | |
174 // a simple cache of constants used within a block | |
175 GrowableArray<LIR_Const*> _constants; | |
176 LIR_OprList _reg_for_constants; | |
177 Values _unpinned_constants; | |
178 | |
179 friend class PhiResolver; | |
180 | |
181 // unified bailout support | |
182 void bailout(const char* msg) const { compilation()->bailout(msg); } | |
183 bool bailed_out() const { return compilation()->bailed_out(); } | |
184 | |
185 void block_do_prolog(BlockBegin* block); | |
186 void block_do_epilog(BlockBegin* block); | |
187 | |
188 // register allocation | |
189 LIR_Opr rlock(Value instr); // lock a free register | |
190 LIR_Opr rlock_result(Value instr); | |
191 LIR_Opr rlock_result(Value instr, BasicType type); | |
192 LIR_Opr rlock_byte(BasicType type); | |
193 LIR_Opr rlock_callee_saved(BasicType type); | |
194 | |
195 // get a constant into a register and get track of what register was used | |
196 LIR_Opr load_constant(Constant* x); | |
197 LIR_Opr load_constant(LIR_Const* constant); | |
198 | |
199 void set_result(Value x, LIR_Opr opr) { | |
200 assert(opr->is_valid(), "must set to valid value"); | |
201 assert(x->operand()->is_illegal(), "operand should never change"); | |
202 assert(!opr->is_register() || opr->is_virtual(), "should never set result to a physical register"); | |
203 x->set_operand(opr); | |
204 assert(opr == x->operand(), "must be"); | |
205 if (opr->is_virtual()) { | |
206 _instruction_for_operand.at_put_grow(opr->vreg_number(), x, NULL); | |
207 } | |
208 } | |
209 void set_no_result(Value x) { assert(!x->has_uses(), "can't have use"); x->clear_operand(); } | |
210 | |
211 friend class LIRItem; | |
212 | |
213 LIR_Opr round_item(LIR_Opr opr); | |
214 LIR_Opr force_to_spill(LIR_Opr value, BasicType t); | |
215 | |
216 void profile_branch(If* if_instr, If::Condition cond); | |
217 | |
218 PhiResolverState& resolver_state() { return _resolver_state; } | |
219 | |
220 void move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_val); | |
221 void move_to_phi(ValueStack* cur_state); | |
222 | |
223 // code emission | |
224 void do_ArithmeticOp_Long (ArithmeticOp* x); | |
225 void do_ArithmeticOp_Int (ArithmeticOp* x); | |
226 void do_ArithmeticOp_FPU (ArithmeticOp* x); | |
227 | |
228 // platform dependent | |
229 LIR_Opr getThreadPointer(); | |
230 | |
231 void do_RegisterFinalizer(Intrinsic* x); | |
232 void do_getClass(Intrinsic* x); | |
233 void do_currentThread(Intrinsic* x); | |
234 void do_MathIntrinsic(Intrinsic* x); | |
235 void do_ArrayCopy(Intrinsic* x); | |
236 void do_CompareAndSwap(Intrinsic* x, ValueType* type); | |
237 void do_AttemptUpdate(Intrinsic* x); | |
238 void do_NIOCheckIndex(Intrinsic* x); | |
239 void do_FPIntrinsics(Intrinsic* x); | |
240 | |
241 void do_UnsafePrefetch(UnsafePrefetch* x, bool is_store); | |
242 | |
243 LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info); | |
244 LIR_Opr call_runtime(BasicTypeArray* signature, LIR_OprList* args, address entry, ValueType* result_type, CodeEmitInfo* info); | |
245 | |
246 // convenience functions | |
247 LIR_Opr call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info); | |
248 LIR_Opr call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info); | |
249 | |
250 // GC Barriers | |
251 | |
252 // generic interface | |
253 | |
342 | 254 void pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info); |
0 | 255 void post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); |
256 | |
257 // specific implementations | |
342 | 258 // pre barriers |
259 | |
260 void G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info); | |
0 | 261 |
262 // post barriers | |
263 | |
342 | 264 void G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); |
0 | 265 void CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); |
266 | |
267 | |
268 static LIR_Opr result_register_for(ValueType* type, bool callee = false); | |
269 | |
270 ciObject* get_jobject_constant(Value value); | |
271 | |
272 LIRItemList* invoke_visit_arguments(Invoke* x); | |
273 void invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list); | |
274 | |
275 void trace_block_entry(BlockBegin* block); | |
276 | |
277 // volatile field operations are never patchable because a klass | |
278 // must be loaded to know it's volatile which means that the offset | |
279 // it always known as well. | |
280 void volatile_field_store(LIR_Opr value, LIR_Address* address, CodeEmitInfo* info); | |
281 void volatile_field_load(LIR_Address* address, LIR_Opr result, CodeEmitInfo* info); | |
282 | |
283 void put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, BasicType type, bool is_volatile); | |
284 void get_Object_unsafe(LIR_Opr dest, LIR_Opr src, LIR_Opr offset, BasicType type, bool is_volatile); | |
285 | |
286 void arithmetic_call_op (Bytecodes::Code code, LIR_Opr result, LIR_OprList* args); | |
287 | |
288 void increment_counter(address counter, int step = 1); | |
289 void increment_counter(LIR_Address* addr, int step = 1); | |
290 | |
291 // increment a counter returning the incremented value | |
292 LIR_Opr increment_and_return_counter(LIR_Opr base, int offset, int increment); | |
293 | |
294 // is_strictfp is only needed for mul and div (and only generates different code on i486) | |
295 void arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp, CodeEmitInfo* info = NULL); | |
296 // machine dependent. returns true if it emitted code for the multiply | |
297 bool strength_reduce_multiply(LIR_Opr left, int constant, LIR_Opr result, LIR_Opr tmp); | |
298 | |
299 void store_stack_parameter (LIR_Opr opr, ByteSize offset_from_sp_in_bytes); | |
300 | |
301 void jobject2reg_with_patching(LIR_Opr r, ciObject* obj, CodeEmitInfo* info); | |
302 | |
303 // this loads the length and compares against the index | |
304 void array_range_check (LIR_Opr array, LIR_Opr index, CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info); | |
305 // For java.nio.Buffer.checkIndex | |
306 void nio_range_check (LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info); | |
307 | |
308 void arithmetic_op_int (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp); | |
309 void arithmetic_op_long (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info = NULL); | |
310 void arithmetic_op_fpu (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp = LIR_OprFact::illegalOpr); | |
311 | |
312 void shift_op (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr value, LIR_Opr count, LIR_Opr tmp); | |
313 | |
314 void logic_op (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr left, LIR_Opr right); | |
315 | |
316 void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
317 void monitor_exit (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no); |
0 | 318 |
319 void new_instance (LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info); | |
320 | |
321 // machine dependent | |
322 void cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info); | |
323 void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info); | |
324 void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info); | |
325 | |
326 void arraycopy_helper(Intrinsic* x, int* flags, ciArrayKlass** expected_type); | |
327 | |
328 // returns a LIR_Address to address an array location. May also | |
329 // emit some code as part of address calculation. If | |
330 // needs_card_mark is true then compute the full address for use by | |
331 // both the store and the card mark. | |
332 LIR_Address* generate_address(LIR_Opr base, | |
333 LIR_Opr index, int shift, | |
334 int disp, | |
335 BasicType type); | |
336 LIR_Address* generate_address(LIR_Opr base, int disp, BasicType type) { | |
337 return generate_address(base, LIR_OprFact::illegalOpr, 0, disp, type); | |
338 } | |
339 LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark); | |
340 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
341 // the helper for generate_address |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
342 void add_large_constant(LIR_Opr src, int c, LIR_Opr dest); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
343 |
0 | 344 // machine preferences and characteristics |
345 bool can_inline_as_constant(Value i) const; | |
346 bool can_inline_as_constant(LIR_Const* c) const; | |
347 bool can_store_as_constant(Value i, BasicType type) const; | |
348 | |
349 LIR_Opr safepoint_poll_register(); | |
350 void increment_invocation_counter(CodeEmitInfo* info, bool backedge = false); | |
351 void increment_backedge_counter(CodeEmitInfo* info) { | |
352 increment_invocation_counter(info, true); | |
353 } | |
354 | |
355 CodeEmitInfo* state_for(Instruction* x, ValueStack* state, bool ignore_xhandler = false); | |
356 CodeEmitInfo* state_for(Instruction* x); | |
357 | |
358 // allocates a virtual register for this instruction if | |
359 // one isn't already allocated. Only for Phi and Local. | |
360 LIR_Opr operand_for_instruction(Instruction *x); | |
361 | |
362 void set_block(BlockBegin* block) { _block = block; } | |
363 | |
364 void block_prolog(BlockBegin* block); | |
365 void block_epilog(BlockBegin* block); | |
366 | |
367 void do_root (Instruction* instr); | |
368 void walk (Instruction* instr); | |
369 | |
370 void bind_block_entry(BlockBegin* block); | |
371 void start_block(BlockBegin* block); | |
372 | |
373 LIR_Opr new_register(BasicType type); | |
374 LIR_Opr new_register(Value value) { return new_register(as_BasicType(value->type())); } | |
375 LIR_Opr new_register(ValueType* type) { return new_register(as_BasicType(type)); } | |
376 | |
377 // returns a register suitable for doing pointer math | |
378 LIR_Opr new_pointer_register() { | |
379 #ifdef _LP64 | |
380 return new_register(T_LONG); | |
381 #else | |
382 return new_register(T_INT); | |
383 #endif | |
384 } | |
385 | |
386 static LIR_Condition lir_cond(If::Condition cond) { | |
387 LIR_Condition l; | |
388 switch (cond) { | |
389 case If::eql: l = lir_cond_equal; break; | |
390 case If::neq: l = lir_cond_notEqual; break; | |
391 case If::lss: l = lir_cond_less; break; | |
392 case If::leq: l = lir_cond_lessEqual; break; | |
393 case If::geq: l = lir_cond_greaterEqual; break; | |
394 case If::gtr: l = lir_cond_greater; break; | |
395 }; | |
396 return l; | |
397 } | |
398 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
399 #ifdef __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
400 void do_soft_float_compare(If *x); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
401 #endif // __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
402 |
0 | 403 void init(); |
404 | |
405 SwitchRangeArray* create_lookup_ranges(TableSwitch* x); | |
406 SwitchRangeArray* create_lookup_ranges(LookupSwitch* x); | |
407 void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux); | |
408 | |
409 public: | |
410 Compilation* compilation() const { return _compilation; } | |
411 FrameMap* frame_map() const { return _compilation->frame_map(); } | |
412 ciMethod* method() const { return _method; } | |
413 BlockBegin* block() const { return _block; } | |
414 IRScope* scope() const { return block()->scope(); } | |
415 | |
416 int max_virtual_register_number() const { return _virtual_register_number; } | |
417 | |
418 void block_do(BlockBegin* block); | |
419 | |
420 // Flags that can be set on vregs | |
421 enum VregFlag { | |
422 must_start_in_memory = 0 // needs to be assigned a memory location at beginning, but may then be loaded in a register | |
423 , callee_saved = 1 // must be in a callee saved register | |
424 , byte_reg = 2 // must be in a byte register | |
425 , num_vreg_flags | |
426 | |
427 }; | |
428 | |
429 LIRGenerator(Compilation* compilation, ciMethod* method) | |
430 : _compilation(compilation) | |
431 , _method(method) | |
432 , _virtual_register_number(LIR_OprDesc::vreg_base) | |
433 , _vreg_flags(NULL, 0, num_vreg_flags) { | |
434 init(); | |
435 } | |
436 | |
437 // for virtual registers, maps them back to Phi's or Local's | |
438 Instruction* instruction_for_opr(LIR_Opr opr); | |
439 Instruction* instruction_for_vreg(int reg_num); | |
440 | |
441 void set_vreg_flag (int vreg_num, VregFlag f); | |
442 bool is_vreg_flag_set(int vreg_num, VregFlag f); | |
443 void set_vreg_flag (LIR_Opr opr, VregFlag f) { set_vreg_flag(opr->vreg_number(), f); } | |
444 bool is_vreg_flag_set(LIR_Opr opr, VregFlag f) { return is_vreg_flag_set(opr->vreg_number(), f); } | |
445 | |
446 // statics | |
447 static LIR_Opr exceptionOopOpr(); | |
448 static LIR_Opr exceptionPcOpr(); | |
449 static LIR_Opr divInOpr(); | |
450 static LIR_Opr divOutOpr(); | |
451 static LIR_Opr remOutOpr(); | |
452 static LIR_Opr shiftCountOpr(); | |
453 LIR_Opr syncTempOpr(); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
454 LIR_Opr atomicLockOpr(); |
0 | 455 |
456 // returns a register suitable for saving the thread in a | |
457 // call_runtime_leaf if one is needed. | |
458 LIR_Opr getThreadTemp(); | |
459 | |
460 // visitor functionality | |
461 virtual void do_Phi (Phi* x); | |
462 virtual void do_Local (Local* x); | |
463 virtual void do_Constant (Constant* x); | |
464 virtual void do_LoadField (LoadField* x); | |
465 virtual void do_StoreField (StoreField* x); | |
466 virtual void do_ArrayLength (ArrayLength* x); | |
467 virtual void do_LoadIndexed (LoadIndexed* x); | |
468 virtual void do_StoreIndexed (StoreIndexed* x); | |
469 virtual void do_NegateOp (NegateOp* x); | |
470 virtual void do_ArithmeticOp (ArithmeticOp* x); | |
471 virtual void do_ShiftOp (ShiftOp* x); | |
472 virtual void do_LogicOp (LogicOp* x); | |
473 virtual void do_CompareOp (CompareOp* x); | |
474 virtual void do_IfOp (IfOp* x); | |
475 virtual void do_Convert (Convert* x); | |
476 virtual void do_NullCheck (NullCheck* x); | |
477 virtual void do_Invoke (Invoke* x); | |
478 virtual void do_NewInstance (NewInstance* x); | |
479 virtual void do_NewTypeArray (NewTypeArray* x); | |
480 virtual void do_NewObjectArray (NewObjectArray* x); | |
481 virtual void do_NewMultiArray (NewMultiArray* x); | |
482 virtual void do_CheckCast (CheckCast* x); | |
483 virtual void do_InstanceOf (InstanceOf* x); | |
484 virtual void do_MonitorEnter (MonitorEnter* x); | |
485 virtual void do_MonitorExit (MonitorExit* x); | |
486 virtual void do_Intrinsic (Intrinsic* x); | |
487 virtual void do_BlockBegin (BlockBegin* x); | |
488 virtual void do_Goto (Goto* x); | |
489 virtual void do_If (If* x); | |
490 virtual void do_IfInstanceOf (IfInstanceOf* x); | |
491 virtual void do_TableSwitch (TableSwitch* x); | |
492 virtual void do_LookupSwitch (LookupSwitch* x); | |
493 virtual void do_Return (Return* x); | |
494 virtual void do_Throw (Throw* x); | |
495 virtual void do_Base (Base* x); | |
496 virtual void do_OsrEntry (OsrEntry* x); | |
497 virtual void do_ExceptionObject(ExceptionObject* x); | |
498 virtual void do_RoundFP (RoundFP* x); | |
499 virtual void do_UnsafeGetRaw (UnsafeGetRaw* x); | |
500 virtual void do_UnsafePutRaw (UnsafePutRaw* x); | |
501 virtual void do_UnsafeGetObject(UnsafeGetObject* x); | |
502 virtual void do_UnsafePutObject(UnsafePutObject* x); | |
503 virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x); | |
504 virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x); | |
505 virtual void do_ProfileCall (ProfileCall* x); | |
506 virtual void do_ProfileCounter (ProfileCounter* x); | |
507 }; | |
508 | |
509 | |
510 class LIRItem: public CompilationResourceObj { | |
511 private: | |
512 Value _value; | |
513 LIRGenerator* _gen; | |
514 LIR_Opr _result; | |
515 bool _destroys_register; | |
516 LIR_Opr _new_result; | |
517 | |
518 LIRGenerator* gen() const { return _gen; } | |
519 | |
520 public: | |
521 LIRItem(Value value, LIRGenerator* gen) { | |
522 _destroys_register = false; | |
523 _gen = gen; | |
524 set_instruction(value); | |
525 } | |
526 | |
527 LIRItem(LIRGenerator* gen) { | |
528 _destroys_register = false; | |
529 _gen = gen; | |
530 _result = LIR_OprFact::illegalOpr; | |
531 set_instruction(NULL); | |
532 } | |
533 | |
534 void set_instruction(Value value) { | |
535 _value = value; | |
536 _result = LIR_OprFact::illegalOpr; | |
537 if (_value != NULL) { | |
538 _gen->walk(_value); | |
539 _result = _value->operand(); | |
540 } | |
541 _new_result = LIR_OprFact::illegalOpr; | |
542 } | |
543 | |
544 Value value() const { return _value; } | |
545 ValueType* type() const { return value()->type(); } | |
546 LIR_Opr result() { | |
547 assert(!_destroys_register || (!_result->is_register() || _result->is_virtual()), | |
548 "shouldn't use set_destroys_register with physical regsiters"); | |
549 if (_destroys_register && _result->is_register()) { | |
550 if (_new_result->is_illegal()) { | |
551 _new_result = _gen->new_register(type()); | |
552 gen()->lir()->move(_result, _new_result); | |
553 } | |
554 return _new_result; | |
555 } else { | |
556 return _result; | |
557 } | |
558 return _result; | |
559 } | |
560 | |
561 void set_result(LIR_Opr opr); | |
562 | |
563 void load_item(); | |
564 void load_byte_item(); | |
565 void load_nonconstant(); | |
566 // load any values which can't be expressed as part of a single store instruction | |
567 void load_for_store(BasicType store_type); | |
568 void load_item_force(LIR_Opr reg); | |
569 | |
570 void dont_load_item() { | |
571 // do nothing | |
572 } | |
573 | |
574 void set_destroys_register() { | |
575 _destroys_register = true; | |
576 } | |
577 | |
578 bool is_constant() const { return value()->as_Constant() != NULL; } | |
579 bool is_stack() { return result()->is_stack(); } | |
580 bool is_register() { return result()->is_register(); } | |
581 | |
582 ciObject* get_jobject_constant() const; | |
583 jint get_jint_constant() const; | |
584 jlong get_jlong_constant() const; | |
585 jfloat get_jfloat_constant() const; | |
586 jdouble get_jdouble_constant() const; | |
587 jint get_address_constant() const; | |
588 }; |