Mercurial > hg > truffle
annotate src/share/vm/c1/c1_LIRAssembler.cpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 0bf37f737702 |
children | 52b4284cb496 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12160
diff
changeset
|
2 * Copyright (c) 2000, 2013, 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:
1378
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
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:
1378
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_Compilation.hpp" | |
27 #include "c1/c1_Instruction.hpp" | |
28 #include "c1/c1_InstructionPrinter.hpp" | |
29 #include "c1/c1_LIRAssembler.hpp" | |
30 #include "c1/c1_MacroAssembler.hpp" | |
31 #include "c1/c1_ValueStack.hpp" | |
32 #include "ci/ciInstance.hpp" | |
33 #ifdef TARGET_ARCH_x86 | |
34 # include "nativeInst_x86.hpp" | |
35 # include "vmreg_x86.inline.hpp" | |
36 #endif | |
37 #ifdef TARGET_ARCH_sparc | |
38 # include "nativeInst_sparc.hpp" | |
39 # include "vmreg_sparc.inline.hpp" | |
40 #endif | |
41 #ifdef TARGET_ARCH_zero | |
42 # include "nativeInst_zero.hpp" | |
43 # include "vmreg_zero.inline.hpp" | |
44 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
45 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
46 # include "nativeInst_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
47 # include "vmreg_arm.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
48 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
49 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
50 # include "nativeInst_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
51 # include "vmreg_ppc.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2089
diff
changeset
|
52 #endif |
0 | 53 |
54 | |
55 void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) { | |
56 // we must have enough patching space so that call can be inserted | |
57 while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeCall::instruction_size) { | |
58 _masm->nop(); | |
59 } | |
60 patch->install(_masm, patch_code, obj, info); | |
17945 | 61 append_code_stub(patch); |
0 | 62 |
63 #ifdef ASSERT | |
1819 | 64 Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci()); |
0 | 65 if (patch->id() == PatchingStub::access_field_id) { |
66 switch (code) { | |
67 case Bytecodes::_putstatic: | |
68 case Bytecodes::_getstatic: | |
69 case Bytecodes::_putfield: | |
70 case Bytecodes::_getfield: | |
71 break; | |
72 default: | |
73 ShouldNotReachHere(); | |
74 } | |
75 } else if (patch->id() == PatchingStub::load_klass_id) { | |
76 switch (code) { | |
77 case Bytecodes::_new: | |
78 case Bytecodes::_anewarray: | |
79 case Bytecodes::_multianewarray: | |
80 case Bytecodes::_instanceof: | |
81 case Bytecodes::_checkcast: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
82 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
83 default: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
84 ShouldNotReachHere(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
85 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
86 } else if (patch->id() == PatchingStub::load_mirror_id) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
87 switch (code) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
88 case Bytecodes::_putstatic: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
89 case Bytecodes::_getstatic: |
0 | 90 case Bytecodes::_ldc: |
91 case Bytecodes::_ldc_w: | |
92 break; | |
93 default: | |
94 ShouldNotReachHere(); | |
95 } | |
12160
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
96 } else if (patch->id() == PatchingStub::load_appendix_id) { |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
97 Bytecodes::Code bc_raw = info->scope()->method()->raw_code_at_bci(info->stack()->bci()); |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
98 assert(Bytecodes::has_optional_appendix(bc_raw), "unexpected appendix resolution"); |
0 | 99 } else { |
100 ShouldNotReachHere(); | |
101 } | |
102 #endif | |
103 } | |
104 | |
12160
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
105 PatchingStub::PatchID LIR_Assembler::patching_id(CodeEmitInfo* info) { |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
106 IRScope* scope = info->scope(); |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
107 Bytecodes::Code bc_raw = scope->method()->raw_code_at_bci(info->stack()->bci()); |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
108 if (Bytecodes::has_optional_appendix(bc_raw)) { |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
109 return PatchingStub::load_appendix_id; |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
110 } |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
111 return PatchingStub::load_mirror_id; |
f98f5d48f511
7199175: JSR 292: C1 needs patching when invokedynamic/invokehandle call site is not linked
roland
parents:
6795
diff
changeset
|
112 } |
0 | 113 |
114 //--------------------------------------------------------------- | |
115 | |
116 | |
117 LIR_Assembler::LIR_Assembler(Compilation* c): | |
118 _compilation(c) | |
119 , _masm(c->masm()) | |
342 | 120 , _bs(Universe::heap()->barrier_set()) |
0 | 121 , _frame_map(c->frame_map()) |
122 , _current_block(NULL) | |
123 , _pending_non_safepoint(NULL) | |
124 , _pending_non_safepoint_offset(0) | |
125 { | |
126 _slow_case_stubs = new CodeStubList(); | |
127 } | |
128 | |
129 | |
130 LIR_Assembler::~LIR_Assembler() { | |
131 } | |
132 | |
133 | |
134 void LIR_Assembler::check_codespace() { | |
135 CodeSection* cs = _masm->code_section(); | |
3896
b346f13112d8
7085279: C1 overflows code buffer with VerifyOops and CompressedOops
iveresov
parents:
2468
diff
changeset
|
136 if (cs->remaining() < (int)(NOT_LP64(1*K)LP64_ONLY(2*K))) { |
0 | 137 BAILOUT("CodeBuffer overflow"); |
138 } | |
139 } | |
140 | |
141 | |
17945 | 142 void LIR_Assembler::append_code_stub(CodeStub* stub) { |
0 | 143 _slow_case_stubs->append(stub); |
144 } | |
145 | |
146 void LIR_Assembler::emit_stubs(CodeStubList* stub_list) { | |
147 for (int m = 0; m < stub_list->length(); m++) { | |
148 CodeStub* s = (*stub_list)[m]; | |
149 | |
150 check_codespace(); | |
151 CHECK_BAILOUT(); | |
152 | |
153 #ifndef PRODUCT | |
154 if (CommentedAssembly) { | |
155 stringStream st; | |
156 s->print_name(&st); | |
157 st.print(" slow case"); | |
158 _masm->block_comment(st.as_string()); | |
159 } | |
160 #endif | |
161 s->emit_code(this); | |
162 #ifdef ASSERT | |
163 s->assert_no_unbound_labels(); | |
164 #endif | |
165 } | |
166 } | |
167 | |
168 | |
169 void LIR_Assembler::emit_slow_case_stubs() { | |
170 emit_stubs(_slow_case_stubs); | |
171 } | |
172 | |
173 | |
174 bool LIR_Assembler::needs_icache(ciMethod* method) const { | |
175 return !method->is_static(); | |
176 } | |
177 | |
178 | |
179 int LIR_Assembler::code_offset() const { | |
180 return _masm->offset(); | |
181 } | |
182 | |
183 | |
184 address LIR_Assembler::pc() const { | |
185 return _masm->pc(); | |
186 } | |
187 | |
17980
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
188 // To bang the stack of this compiled method we use the stack size |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
189 // that the interpreter would need in case of a deoptimization. This |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
190 // removes the need to bang the stack in the deoptimization blob which |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
191 // in turn simplifies stack overflow handling. |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
192 int LIR_Assembler::bang_size_in_bytes() const { |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
193 return MAX2(initial_frame_size_in_bytes(), _compilation->interpreter_frame_size()); |
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
194 } |
0 | 195 |
196 void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) { | |
197 for (int i = 0; i < info_list->length(); i++) { | |
198 XHandlers* handlers = info_list->at(i)->exception_handlers(); | |
199 | |
200 for (int j = 0; j < handlers->length(); j++) { | |
201 XHandler* handler = handlers->handler_at(j); | |
202 assert(handler->lir_op_id() != -1, "handler not processed by LinearScan"); | |
203 assert(handler->entry_code() == NULL || | |
204 handler->entry_code()->instructions_list()->last()->code() == lir_branch || | |
205 handler->entry_code()->instructions_list()->last()->code() == lir_delay_slot, "last operation must be branch"); | |
206 | |
207 if (handler->entry_pco() == -1) { | |
208 // entry code not emitted yet | |
209 if (handler->entry_code() != NULL && handler->entry_code()->instructions_list()->length() > 1) { | |
210 handler->set_entry_pco(code_offset()); | |
211 if (CommentedAssembly) { | |
212 _masm->block_comment("Exception adapter block"); | |
213 } | |
214 emit_lir_list(handler->entry_code()); | |
215 } else { | |
216 handler->set_entry_pco(handler->entry_block()->exception_handler_pco()); | |
217 } | |
218 | |
219 assert(handler->entry_pco() != -1, "must be set now"); | |
220 } | |
221 } | |
222 } | |
223 } | |
224 | |
225 | |
226 void LIR_Assembler::emit_code(BlockList* hir) { | |
227 if (PrintLIR) { | |
228 print_LIR(hir); | |
229 } | |
230 | |
231 int n = hir->length(); | |
232 for (int i = 0; i < n; i++) { | |
233 emit_block(hir->at(i)); | |
234 CHECK_BAILOUT(); | |
235 } | |
236 | |
237 flush_debug_info(code_offset()); | |
238 | |
239 DEBUG_ONLY(check_no_unbound_labels()); | |
240 } | |
241 | |
242 | |
243 void LIR_Assembler::emit_block(BlockBegin* block) { | |
244 if (block->is_set(BlockBegin::backward_branch_target_flag)) { | |
245 align_backward_branch_target(); | |
246 } | |
247 | |
248 // if this block is the start of an exception handler, record the | |
249 // PC offset of the first instruction for later construction of | |
250 // the ExceptionHandlerTable | |
251 if (block->is_set(BlockBegin::exception_entry_flag)) { | |
252 block->set_exception_handler_pco(code_offset()); | |
253 } | |
254 | |
255 #ifndef PRODUCT | |
256 if (PrintLIRWithAssembly) { | |
257 // don't print Phi's | |
258 InstructionPrinter ip(false); | |
259 block->print(ip); | |
260 } | |
261 #endif /* PRODUCT */ | |
262 | |
263 assert(block->lir() != NULL, "must have LIR"); | |
304 | 264 X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); |
0 | 265 |
266 #ifndef PRODUCT | |
267 if (CommentedAssembly) { | |
268 stringStream st; | |
1819 | 269 st.print_cr(" block B%d [%d, %d]", block->block_id(), block->bci(), block->end()->printable_bci()); |
0 | 270 _masm->block_comment(st.as_string()); |
271 } | |
272 #endif | |
273 | |
274 emit_lir_list(block->lir()); | |
275 | |
304 | 276 X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); |
0 | 277 } |
278 | |
279 | |
280 void LIR_Assembler::emit_lir_list(LIR_List* list) { | |
281 peephole(list); | |
282 | |
283 int n = list->length(); | |
284 for (int i = 0; i < n; i++) { | |
285 LIR_Op* op = list->at(i); | |
286 | |
287 check_codespace(); | |
288 CHECK_BAILOUT(); | |
289 | |
290 #ifndef PRODUCT | |
291 if (CommentedAssembly) { | |
292 // Don't record out every op since that's too verbose. Print | |
293 // branches since they include block and stub names. Also print | |
294 // patching moves since they generate funny looking code. | |
295 if (op->code() == lir_branch || | |
296 (op->code() == lir_move && op->as_Op1()->patch_code() != lir_patch_none)) { | |
297 stringStream st; | |
298 op->print_on(&st); | |
299 _masm->block_comment(st.as_string()); | |
300 } | |
301 } | |
302 if (PrintLIRWithAssembly) { | |
303 // print out the LIR operation followed by the resulting assembly | |
304 list->at(i)->print(); tty->cr(); | |
305 } | |
306 #endif /* PRODUCT */ | |
307 | |
308 op->emit_code(this); | |
309 | |
310 if (compilation()->debug_info_recorder()->recording_non_safepoints()) { | |
311 process_debug_info(op); | |
312 } | |
313 | |
314 #ifndef PRODUCT | |
315 if (PrintLIRWithAssembly) { | |
316 _masm->code()->decode(); | |
317 } | |
318 #endif /* PRODUCT */ | |
319 } | |
320 } | |
321 | |
322 #ifdef ASSERT | |
323 void LIR_Assembler::check_no_unbound_labels() { | |
324 CHECK_BAILOUT(); | |
325 | |
326 for (int i = 0; i < _branch_target_blocks.length() - 1; i++) { | |
327 if (!_branch_target_blocks.at(i)->label()->is_bound()) { | |
328 tty->print_cr("label of block B%d is not bound", _branch_target_blocks.at(i)->block_id()); | |
329 assert(false, "unbound label"); | |
330 } | |
331 } | |
332 } | |
333 #endif | |
334 | |
335 //----------------------------------debug info-------------------------------- | |
336 | |
337 | |
338 void LIR_Assembler::add_debug_info_for_branch(CodeEmitInfo* info) { | |
339 _masm->code_section()->relocate(pc(), relocInfo::poll_type); | |
340 int pc_offset = code_offset(); | |
341 flush_debug_info(pc_offset); | |
342 info->record_debug_info(compilation()->debug_info_recorder(), pc_offset); | |
343 if (info->exception_handlers() != NULL) { | |
344 compilation()->add_exception_handlers_for_pco(pc_offset, info->exception_handlers()); | |
345 } | |
346 } | |
347 | |
348 | |
1564 | 349 void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo) { |
0 | 350 flush_debug_info(pc_offset); |
1564 | 351 cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset); |
0 | 352 if (cinfo->exception_handlers() != NULL) { |
353 compilation()->add_exception_handlers_for_pco(pc_offset, cinfo->exception_handlers()); | |
354 } | |
355 } | |
356 | |
357 static ValueStack* debug_info(Instruction* ins) { | |
358 StateSplit* ss = ins->as_StateSplit(); | |
359 if (ss != NULL) return ss->state(); | |
1819 | 360 return ins->state_before(); |
0 | 361 } |
362 | |
363 void LIR_Assembler::process_debug_info(LIR_Op* op) { | |
364 Instruction* src = op->source(); | |
365 if (src == NULL) return; | |
366 int pc_offset = code_offset(); | |
367 if (_pending_non_safepoint == src) { | |
368 _pending_non_safepoint_offset = pc_offset; | |
369 return; | |
370 } | |
371 ValueStack* vstack = debug_info(src); | |
372 if (vstack == NULL) return; | |
373 if (_pending_non_safepoint != NULL) { | |
374 // Got some old debug info. Get rid of it. | |
1819 | 375 if (debug_info(_pending_non_safepoint) == vstack) { |
0 | 376 _pending_non_safepoint_offset = pc_offset; |
377 return; | |
378 } | |
379 if (_pending_non_safepoint_offset < pc_offset) { | |
380 record_non_safepoint_debug_info(); | |
381 } | |
382 _pending_non_safepoint = NULL; | |
383 } | |
384 // Remember the debug info. | |
385 if (pc_offset > compilation()->debug_info_recorder()->last_pc_offset()) { | |
386 _pending_non_safepoint = src; | |
387 _pending_non_safepoint_offset = pc_offset; | |
388 } | |
389 } | |
390 | |
391 // Index caller states in s, where 0 is the oldest, 1 its callee, etc. | |
392 // Return NULL if n is too large. | |
393 // Returns the caller_bci for the next-younger state, also. | |
394 static ValueStack* nth_oldest(ValueStack* s, int n, int& bci_result) { | |
395 ValueStack* t = s; | |
396 for (int i = 0; i < n; i++) { | |
397 if (t == NULL) break; | |
398 t = t->caller_state(); | |
399 } | |
400 if (t == NULL) return NULL; | |
401 for (;;) { | |
402 ValueStack* tc = t->caller_state(); | |
403 if (tc == NULL) return s; | |
404 t = tc; | |
1819 | 405 bci_result = tc->bci(); |
0 | 406 s = s->caller_state(); |
407 } | |
408 } | |
409 | |
410 void LIR_Assembler::record_non_safepoint_debug_info() { | |
411 int pc_offset = _pending_non_safepoint_offset; | |
412 ValueStack* vstack = debug_info(_pending_non_safepoint); | |
1819 | 413 int bci = vstack->bci(); |
0 | 414 |
415 DebugInformationRecorder* debug_info = compilation()->debug_info_recorder(); | |
416 assert(debug_info->recording_non_safepoints(), "sanity"); | |
417 | |
418 debug_info->add_non_safepoint(pc_offset); | |
419 | |
420 // Visit scopes from oldest to youngest. | |
421 for (int n = 0; ; n++) { | |
422 int s_bci = bci; | |
423 ValueStack* s = nth_oldest(vstack, n, s_bci); | |
424 if (s == NULL) break; | |
425 IRScope* scope = s->scope(); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
380
diff
changeset
|
426 //Always pass false for reexecute since these ScopeDescs are never used for deopt |
1819 | 427 debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/); |
0 | 428 } |
429 | |
430 debug_info->end_non_safepoint(pc_offset); | |
431 } | |
432 | |
433 | |
434 void LIR_Assembler::add_debug_info_for_null_check_here(CodeEmitInfo* cinfo) { | |
435 add_debug_info_for_null_check(code_offset(), cinfo); | |
436 } | |
437 | |
438 void LIR_Assembler::add_debug_info_for_null_check(int pc_offset, CodeEmitInfo* cinfo) { | |
439 ImplicitNullCheckStub* stub = new ImplicitNullCheckStub(pc_offset, cinfo); | |
17945 | 440 append_code_stub(stub); |
0 | 441 } |
442 | |
443 void LIR_Assembler::add_debug_info_for_div0_here(CodeEmitInfo* info) { | |
444 add_debug_info_for_div0(code_offset(), info); | |
445 } | |
446 | |
447 void LIR_Assembler::add_debug_info_for_div0(int pc_offset, CodeEmitInfo* cinfo) { | |
448 DivByZeroStub* stub = new DivByZeroStub(pc_offset, cinfo); | |
17945 | 449 append_code_stub(stub); |
0 | 450 } |
451 | |
452 void LIR_Assembler::emit_rtcall(LIR_OpRTCall* op) { | |
453 rt_call(op->result_opr(), op->addr(), op->arguments(), op->tmp(), op->info()); | |
454 } | |
455 | |
456 | |
457 void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { | |
458 verify_oop_map(op->info()); | |
459 | |
460 if (os::is_MP()) { | |
461 // must align calls sites, otherwise they can't be updated atomically on MP hardware | |
462 align_call(op->code()); | |
463 } | |
464 | |
465 // emit the static call stub stuff out of line | |
466 emit_static_call_stub(); | |
467 | |
468 switch (op->code()) { | |
469 case lir_static_call: | |
6616
7a302948f5a4
7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents:
6084
diff
changeset
|
470 case lir_dynamic_call: |
1295 | 471 call(op, relocInfo::static_call_type); |
0 | 472 break; |
473 case lir_optvirtual_call: | |
1295 | 474 call(op, relocInfo::opt_virtual_call_type); |
0 | 475 break; |
476 case lir_icvirtual_call: | |
1295 | 477 ic_call(op); |
0 | 478 break; |
479 case lir_virtual_call: | |
1295 | 480 vtable_call(op); |
0 | 481 break; |
6616
7a302948f5a4
7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents:
6084
diff
changeset
|
482 default: |
7a302948f5a4
7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents:
6084
diff
changeset
|
483 fatal(err_msg_res("unexpected op code: %s", op->name())); |
7a302948f5a4
7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents:
6084
diff
changeset
|
484 break; |
0 | 485 } |
1295 | 486 |
1691
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1579
diff
changeset
|
487 // JSR 292 |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1579
diff
changeset
|
488 // Record if this method has MethodHandle invokes. |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1579
diff
changeset
|
489 if (op->is_method_handle_invoke()) { |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1579
diff
changeset
|
490 compilation()->set_has_method_handle_invokes(true); |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1579
diff
changeset
|
491 } |
4a665be40fd3
6975855: don't emit deopt MH handler in C1 if not required
twisti
parents:
1579
diff
changeset
|
492 |
304 | 493 #if defined(X86) && defined(TIERED) |
0 | 494 // C2 leave fpu stack dirty clean it |
495 if (UseSSE < 2) { | |
496 int i; | |
497 for ( i = 1; i <= 7 ; i++ ) { | |
498 ffree(i); | |
499 } | |
500 if (!op->result_opr()->is_float_kind()) { | |
501 ffree(0); | |
502 } | |
503 } | |
304 | 504 #endif // X86 && TIERED |
0 | 505 } |
506 | |
507 | |
508 void LIR_Assembler::emit_opLabel(LIR_OpLabel* op) { | |
509 _masm->bind (*(op->label())); | |
510 } | |
511 | |
512 | |
513 void LIR_Assembler::emit_op1(LIR_Op1* op) { | |
514 switch (op->code()) { | |
515 case lir_move: | |
516 if (op->move_kind() == lir_move_volatile) { | |
517 assert(op->patch_code() == lir_patch_none, "can't patch volatiles"); | |
518 volatile_move_op(op->in_opr(), op->result_opr(), op->type(), op->info()); | |
519 } else { | |
520 move_op(op->in_opr(), op->result_opr(), op->type(), | |
2002 | 521 op->patch_code(), op->info(), op->pop_fpu_stack(), |
522 op->move_kind() == lir_move_unaligned, | |
523 op->move_kind() == lir_move_wide); | |
0 | 524 } |
525 break; | |
526 | |
527 case lir_prefetchr: | |
528 prefetchr(op->in_opr()); | |
529 break; | |
530 | |
531 case lir_prefetchw: | |
532 prefetchw(op->in_opr()); | |
533 break; | |
534 | |
535 case lir_roundfp: { | |
536 LIR_OpRoundFP* round_op = op->as_OpRoundFP(); | |
537 roundfp_op(round_op->in_opr(), round_op->tmp(), round_op->result_opr(), round_op->pop_fpu_stack()); | |
538 break; | |
539 } | |
540 | |
541 case lir_return: | |
542 return_op(op->in_opr()); | |
543 break; | |
544 | |
545 case lir_safepoint: | |
546 if (compilation()->debug_info_recorder()->last_pc_offset() == code_offset()) { | |
547 _masm->nop(); | |
548 } | |
549 safepoint_poll(op->in_opr(), op->info()); | |
550 break; | |
551 | |
552 case lir_fxch: | |
553 fxch(op->in_opr()->as_jint()); | |
554 break; | |
555 | |
556 case lir_fld: | |
557 fld(op->in_opr()->as_jint()); | |
558 break; | |
559 | |
560 case lir_ffree: | |
561 ffree(op->in_opr()->as_jint()); | |
562 break; | |
563 | |
564 case lir_branch: | |
565 break; | |
566 | |
567 case lir_push: | |
568 push(op->in_opr()); | |
569 break; | |
570 | |
571 case lir_pop: | |
572 pop(op->in_opr()); | |
573 break; | |
574 | |
575 case lir_neg: | |
576 negate(op->in_opr(), op->result_opr()); | |
577 break; | |
578 | |
579 case lir_leal: | |
580 leal(op->in_opr(), op->result_opr()); | |
581 break; | |
582 | |
583 case lir_null_check: | |
584 if (GenerateCompilerNullChecks) { | |
585 add_debug_info_for_null_check_here(op->info()); | |
586 | |
587 if (op->in_opr()->is_single_cpu()) { | |
588 _masm->null_check(op->in_opr()->as_register()); | |
589 } else { | |
590 Unimplemented(); | |
591 } | |
592 } | |
593 break; | |
594 | |
595 case lir_monaddr: | |
596 monitor_address(op->in_opr()->as_constant_ptr()->as_jint(), op->result_opr()); | |
597 break; | |
598 | |
1783 | 599 #ifdef SPARC |
600 case lir_pack64: | |
601 pack64(op->in_opr(), op->result_opr()); | |
602 break; | |
603 | |
604 case lir_unpack64: | |
605 unpack64(op->in_opr(), op->result_opr()); | |
606 break; | |
607 #endif | |
608 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1301
diff
changeset
|
609 case lir_unwind: |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1301
diff
changeset
|
610 unwind_op(op->in_opr()); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1301
diff
changeset
|
611 break; |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1301
diff
changeset
|
612 |
0 | 613 default: |
614 Unimplemented(); | |
615 break; | |
616 } | |
617 } | |
618 | |
619 | |
620 void LIR_Assembler::emit_op0(LIR_Op0* op) { | |
621 switch (op->code()) { | |
622 case lir_word_align: { | |
623 while (code_offset() % BytesPerWord != 0) { | |
624 _masm->nop(); | |
625 } | |
626 break; | |
627 } | |
628 | |
629 case lir_nop: | |
630 assert(op->info() == NULL, "not supported"); | |
631 _masm->nop(); | |
632 break; | |
633 | |
634 case lir_label: | |
635 Unimplemented(); | |
636 break; | |
637 | |
638 case lir_build_frame: | |
639 build_frame(); | |
640 break; | |
641 | |
642 case lir_std_entry: | |
643 // init offsets | |
644 offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset()); | |
645 _masm->align(CodeEntryAlignment); | |
646 if (needs_icache(compilation()->method())) { | |
647 check_icache(); | |
648 } | |
649 offsets()->set_value(CodeOffsets::Verified_Entry, _masm->offset()); | |
650 _masm->verified_entry(); | |
651 build_frame(); | |
652 offsets()->set_value(CodeOffsets::Frame_Complete, _masm->offset()); | |
653 break; | |
654 | |
655 case lir_osr_entry: | |
656 offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset()); | |
657 osr_entry(); | |
658 break; | |
659 | |
660 case lir_24bit_FPU: | |
661 set_24bit_FPU(); | |
662 break; | |
663 | |
664 case lir_reset_FPU: | |
665 reset_FPU(); | |
666 break; | |
667 | |
668 case lir_breakpoint: | |
669 breakpoint(); | |
670 break; | |
671 | |
672 case lir_fpop_raw: | |
673 fpop(); | |
674 break; | |
675 | |
676 case lir_membar: | |
677 membar(); | |
678 break; | |
679 | |
680 case lir_membar_acquire: | |
681 membar_acquire(); | |
682 break; | |
683 | |
684 case lir_membar_release: | |
685 membar_release(); | |
686 break; | |
687 | |
4966
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
688 case lir_membar_loadload: |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
689 membar_loadload(); |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
690 break; |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
691 |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
692 case lir_membar_storestore: |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
693 membar_storestore(); |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
694 break; |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
695 |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
696 case lir_membar_loadstore: |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
697 membar_loadstore(); |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
698 break; |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
699 |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
700 case lir_membar_storeload: |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
701 membar_storeload(); |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
702 break; |
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
3896
diff
changeset
|
703 |
0 | 704 case lir_get_thread: |
705 get_thread(op->result_opr()); | |
706 break; | |
707 | |
708 default: | |
709 ShouldNotReachHere(); | |
710 break; | |
711 } | |
712 } | |
713 | |
714 | |
715 void LIR_Assembler::emit_op2(LIR_Op2* op) { | |
716 switch (op->code()) { | |
717 case lir_cmp: | |
718 if (op->info() != NULL) { | |
719 assert(op->in_opr1()->is_address() || op->in_opr2()->is_address(), | |
720 "shouldn't be codeemitinfo for non-address operands"); | |
721 add_debug_info_for_null_check_here(op->info()); // exception possible | |
722 } | |
723 comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op); | |
724 break; | |
725 | |
726 case lir_cmp_l2i: | |
727 case lir_cmp_fd2i: | |
728 case lir_ucmp_fd2i: | |
729 comp_fl2i(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op); | |
730 break; | |
731 | |
732 case lir_cmove: | |
2089
037c727f35fb
7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents:
2002
diff
changeset
|
733 cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type()); |
0 | 734 break; |
735 | |
736 case lir_shl: | |
737 case lir_shr: | |
738 case lir_ushr: | |
739 if (op->in_opr2()->is_constant()) { | |
740 shift_op(op->code(), op->in_opr1(), op->in_opr2()->as_constant_ptr()->as_jint(), op->result_opr()); | |
741 } else { | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4966
diff
changeset
|
742 shift_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr()); |
0 | 743 } |
744 break; | |
745 | |
746 case lir_add: | |
747 case lir_sub: | |
748 case lir_mul: | |
749 case lir_mul_strictfp: | |
750 case lir_div: | |
751 case lir_div_strictfp: | |
752 case lir_rem: | |
753 assert(op->fpu_pop_count() < 2, ""); | |
754 arith_op( | |
755 op->code(), | |
756 op->in_opr1(), | |
757 op->in_opr2(), | |
758 op->result_opr(), | |
759 op->info(), | |
760 op->fpu_pop_count() == 1); | |
761 break; | |
762 | |
763 case lir_abs: | |
764 case lir_sqrt: | |
765 case lir_sin: | |
766 case lir_tan: | |
767 case lir_cos: | |
768 case lir_log: | |
769 case lir_log10: | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4966
diff
changeset
|
770 case lir_exp: |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4966
diff
changeset
|
771 case lir_pow: |
0 | 772 intrinsic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op); |
773 break; | |
774 | |
775 case lir_logic_and: | |
776 case lir_logic_or: | |
777 case lir_logic_xor: | |
778 logic_op( | |
779 op->code(), | |
780 op->in_opr1(), | |
781 op->in_opr2(), | |
782 op->result_opr()); | |
783 break; | |
784 | |
785 case lir_throw: | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1301
diff
changeset
|
786 throw_op(op->in_opr1(), op->in_opr2(), op->info()); |
0 | 787 break; |
788 | |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6725
diff
changeset
|
789 case lir_xadd: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6725
diff
changeset
|
790 case lir_xchg: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6725
diff
changeset
|
791 atomic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr()); |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6725
diff
changeset
|
792 break; |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6725
diff
changeset
|
793 |
0 | 794 default: |
795 Unimplemented(); | |
796 break; | |
797 } | |
798 } | |
799 | |
800 | |
801 void LIR_Assembler::build_frame() { | |
17980
0bf37f737702
8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
roland
parents:
17945
diff
changeset
|
802 _masm->build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes()); |
0 | 803 } |
804 | |
805 | |
806 void LIR_Assembler::roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack) { | |
807 assert((src->is_single_fpu() && dest->is_single_stack()) || | |
808 (src->is_double_fpu() && dest->is_double_stack()), | |
809 "round_fp: rounds register -> stack location"); | |
810 | |
811 reg2stack (src, dest, src->type(), pop_fpu_stack); | |
812 } | |
813 | |
814 | |
2002 | 815 void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide) { |
0 | 816 if (src->is_register()) { |
817 if (dest->is_register()) { | |
818 assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); | |
819 reg2reg(src, dest); | |
820 } else if (dest->is_stack()) { | |
821 assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); | |
822 reg2stack(src, dest, type, pop_fpu_stack); | |
823 } else if (dest->is_address()) { | |
2002 | 824 reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, wide, unaligned); |
0 | 825 } else { |
826 ShouldNotReachHere(); | |
827 } | |
828 | |
829 } else if (src->is_stack()) { | |
830 assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); | |
831 if (dest->is_register()) { | |
832 stack2reg(src, dest, type); | |
833 } else if (dest->is_stack()) { | |
834 stack2stack(src, dest, type); | |
835 } else { | |
836 ShouldNotReachHere(); | |
837 } | |
838 | |
839 } else if (src->is_constant()) { | |
840 if (dest->is_register()) { | |
841 const2reg(src, dest, patch_code, info); // patching is possible | |
842 } else if (dest->is_stack()) { | |
843 assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here"); | |
844 const2stack(src, dest); | |
845 } else if (dest->is_address()) { | |
846 assert(patch_code == lir_patch_none, "no patching allowed here"); | |
2002 | 847 const2mem(src, dest, type, info, wide); |
0 | 848 } else { |
849 ShouldNotReachHere(); | |
850 } | |
851 | |
852 } else if (src->is_address()) { | |
2002 | 853 mem2reg(src, dest, type, patch_code, info, wide, unaligned); |
0 | 854 |
855 } else { | |
856 ShouldNotReachHere(); | |
857 } | |
858 } | |
859 | |
860 | |
861 void LIR_Assembler::verify_oop_map(CodeEmitInfo* info) { | |
862 #ifndef PRODUCT | |
17623
ef54656d5a65
8011391: C1: assert(code_offset() - offset == NativeInstruction::nop_instruction_size) failed: only one instruction can go in a delay slot
adlertz
parents:
17467
diff
changeset
|
863 if (VerifyOops) { |
0 | 864 OopMapStream s(info->oop_map()); |
865 while (!s.is_done()) { | |
866 OopMapValue v = s.current(); | |
867 if (v.is_oop()) { | |
868 VMReg r = v.reg(); | |
869 if (!r->is_stack()) { | |
870 stringStream st; | |
871 st.print("bad oop %s at %d", r->as_Register()->name(), _masm->offset()); | |
872 #ifdef SPARC | |
873 _masm->_verify_oop(r->as_Register(), strdup(st.as_string()), __FILE__, __LINE__); | |
874 #else | |
875 _masm->verify_oop(r->as_Register()); | |
876 #endif | |
877 } else { | |
878 _masm->verify_stack_oop(r->reg2stack() * VMRegImpl::stack_slot_size); | |
879 } | |
880 } | |
2451
87ce328c6a21
6528013: C1 CTW failure with -XX:+VerifyOops assert(allocates2(pc),"")
never
parents:
2192
diff
changeset
|
881 check_codespace(); |
87ce328c6a21
6528013: C1 CTW failure with -XX:+VerifyOops assert(allocates2(pc),"")
never
parents:
2192
diff
changeset
|
882 CHECK_BAILOUT(); |
87ce328c6a21
6528013: C1 CTW failure with -XX:+VerifyOops assert(allocates2(pc),"")
never
parents:
2192
diff
changeset
|
883 |
0 | 884 s.next(); |
885 } | |
886 } | |
887 #endif | |
888 } |