Mercurial > hg > truffle
comparison src/cpu/ppc/vm/macroAssembler_ppc.cpp @ 17807:71a71b0bc844
8037915: PPC64/AIX: Several smaller fixes
Reviewed-by: kvn
author | goetz |
---|---|
date | Thu, 20 Mar 2014 11:03:06 +0100 |
parents | fd1b9f02cc91 |
children | f6bde7889409 |
comparison
equal
deleted
inserted
replaced
17806:9200402b42d5 | 17807:71a71b0bc844 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * Copyright 2012, 2013 SAP AG. All rights reserved. | 3 * Copyright 2012, 2014 SAP AG. All rights reserved. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 * | 5 * |
6 * This code is free software; you can redistribute it and/or modify it | 6 * This code is free software; you can redistribute it and/or modify it |
7 * under the terms of the GNU General Public License version 2 only, as | 7 * under the terms of the GNU General Public License version 2 only, as |
8 * published by the Free Software Foundation. | 8 * published by the Free Software Foundation. |
22 * questions. | 22 * questions. |
23 * | 23 * |
24 */ | 24 */ |
25 | 25 |
26 #include "precompiled.hpp" | 26 #include "precompiled.hpp" |
27 #include "asm/assembler.hpp" | |
28 #include "asm/assembler.inline.hpp" | |
29 #include "asm/macroAssembler.inline.hpp" | 27 #include "asm/macroAssembler.inline.hpp" |
30 #include "compiler/disassembler.hpp" | 28 #include "compiler/disassembler.hpp" |
31 #include "gc_interface/collectedHeap.inline.hpp" | 29 #include "gc_interface/collectedHeap.inline.hpp" |
32 #include "interpreter/interpreter.hpp" | 30 #include "interpreter/interpreter.hpp" |
33 #include "memory/cardTableModRefBS.hpp" | 31 #include "memory/cardTableModRefBS.hpp" |
1118 bl64_patchable(fd->entry(), rt); | 1116 bl64_patchable(fd->entry(), rt); |
1119 _last_calls_return_pc = pc(); | 1117 _last_calls_return_pc = pc(); |
1120 } | 1118 } |
1121 return _last_calls_return_pc; | 1119 return _last_calls_return_pc; |
1122 } | 1120 } |
1123 #endif | 1121 #endif // ABI_ELFv2 |
1124 | 1122 |
1125 void MacroAssembler::call_VM_base(Register oop_result, | 1123 void MacroAssembler::call_VM_base(Register oop_result, |
1126 Register last_java_sp, | 1124 Register last_java_sp, |
1127 address entry_point, | 1125 address entry_point, |
1128 bool check_exceptions) { | 1126 bool check_exceptions) { |
1792 | 1790 |
1793 andi(temp_reg, mark_reg, markOopDesc::biased_lock_mask_in_place); | 1791 andi(temp_reg, mark_reg, markOopDesc::biased_lock_mask_in_place); |
1794 cmpwi(cr_reg, temp_reg, markOopDesc::biased_lock_pattern); | 1792 cmpwi(cr_reg, temp_reg, markOopDesc::biased_lock_pattern); |
1795 bne(cr_reg, cas_label); | 1793 bne(cr_reg, cas_label); |
1796 | 1794 |
1797 load_klass_with_trap_null_check(temp_reg, obj_reg); | 1795 load_klass(temp_reg, obj_reg); |
1798 | 1796 |
1799 load_const_optimized(temp2_reg, ~((int) markOopDesc::age_mask_in_place)); | 1797 load_const_optimized(temp2_reg, ~((int) markOopDesc::age_mask_in_place)); |
1800 ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg); | 1798 ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg); |
1801 orr(temp_reg, R16_thread, temp_reg); | 1799 orr(temp_reg, R16_thread, temp_reg); |
1802 xorr(temp_reg, mark_reg, temp_reg); | 1800 xorr(temp_reg, mark_reg, temp_reg); |
1889 // value as the comparison value when doing the cas to acquire the | 1887 // value as the comparison value when doing the cas to acquire the |
1890 // bias in the current epoch. In other words, we allow transfer of | 1888 // bias in the current epoch. In other words, we allow transfer of |
1891 // the bias from one thread to another directly in this situation. | 1889 // the bias from one thread to another directly in this situation. |
1892 andi(temp_reg, mark_reg, markOopDesc::age_mask_in_place); | 1890 andi(temp_reg, mark_reg, markOopDesc::age_mask_in_place); |
1893 orr(temp_reg, R16_thread, temp_reg); | 1891 orr(temp_reg, R16_thread, temp_reg); |
1894 load_klass_with_trap_null_check(temp2_reg, obj_reg); | 1892 load_klass(temp2_reg, obj_reg); |
1895 ld(temp2_reg, in_bytes(Klass::prototype_header_offset()), temp2_reg); | 1893 ld(temp2_reg, in_bytes(Klass::prototype_header_offset()), temp2_reg); |
1896 orr(temp_reg, temp_reg, temp2_reg); | 1894 orr(temp_reg, temp_reg, temp2_reg); |
1897 | 1895 |
1898 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); | 1896 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); |
1899 | 1897 |
1925 // this object to the prototype value and fall through to the | 1923 // this object to the prototype value and fall through to the |
1926 // CAS-based locking scheme. Note that if our CAS fails, it means | 1924 // CAS-based locking scheme. Note that if our CAS fails, it means |
1927 // that another thread raced us for the privilege of revoking the | 1925 // that another thread raced us for the privilege of revoking the |
1928 // bias of this particular object, so it's okay to continue in the | 1926 // bias of this particular object, so it's okay to continue in the |
1929 // normal locking code. | 1927 // normal locking code. |
1930 load_klass_with_trap_null_check(temp_reg, obj_reg); | 1928 load_klass(temp_reg, obj_reg); |
1931 ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg); | 1929 ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg); |
1932 andi(temp2_reg, mark_reg, markOopDesc::age_mask_in_place); | 1930 andi(temp2_reg, mark_reg, markOopDesc::age_mask_in_place); |
1933 orr(temp_reg, temp_reg, temp2_reg); | 1931 orr(temp_reg, temp_reg, temp2_reg); |
1934 | 1932 |
1935 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); | 1933 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); |
2211 li(R0, 0); // dirty | 2209 li(R0, 0); // dirty |
2212 if (UseConcMarkSweepGC) membar(Assembler::StoreStore); | 2210 if (UseConcMarkSweepGC) membar(Assembler::StoreStore); |
2213 stbx(R0, Rtmp, Robj); | 2211 stbx(R0, Rtmp, Robj); |
2214 } | 2212 } |
2215 | 2213 |
2216 #ifndef SERIALGC | 2214 #if INCLUDE_ALL_GCS |
2217 | |
2218 // General G1 pre-barrier generator. | 2215 // General G1 pre-barrier generator. |
2219 // Goal: record the previous value if it is not null. | 2216 // Goal: record the previous value if it is not null. |
2220 void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val, | 2217 void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val, |
2221 Register Rtmp1, Register Rtmp2, bool needs_frame) { | 2218 Register Rtmp1, Register Rtmp2, bool needs_frame) { |
2222 Label runtime, filtered; | 2219 Label runtime, filtered; |
2326 | 2323 |
2327 srdi(Rcard_addr, Rstore_addr, CardTableModRefBS::card_shift); | 2324 srdi(Rcard_addr, Rstore_addr, CardTableModRefBS::card_shift); |
2328 | 2325 |
2329 // Get the address of the card. | 2326 // Get the address of the card. |
2330 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); | 2327 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); |
2331 | 2328 cmpwi(CCR0, Rtmp3, (int)G1SATBCardTableModRefBS::g1_young_card_val()); |
2332 assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code"); | 2329 beq(CCR0, filtered); |
2333 cmpwi(CCR0, Rtmp3 /* card value */, 0); | 2330 |
2331 membar(Assembler::StoreLoad); | |
2332 lbzx(/*card value*/ Rtmp3, Rbase, Rcard_addr); // Reload after membar. | |
2333 cmpwi(CCR0, Rtmp3 /* card value */, CardTableModRefBS::dirty_card_val()); | |
2334 beq(CCR0, filtered); | 2334 beq(CCR0, filtered); |
2335 | 2335 |
2336 // Storing a region crossing, non-NULL oop, card is clean. | 2336 // Storing a region crossing, non-NULL oop, card is clean. |
2337 // Dirty card and log. | 2337 // Dirty card and log. |
2338 li(Rtmp3, 0); // dirty | 2338 li(Rtmp3, CardTableModRefBS::dirty_card_val()); |
2339 //release(); // G1: oops are allowed to get visible after dirty marking. | 2339 //release(); // G1: oops are allowed to get visible after dirty marking. |
2340 stbx(Rtmp3, Rbase, Rcard_addr); | 2340 stbx(Rtmp3, Rbase, Rcard_addr); |
2341 | 2341 |
2342 add(Rcard_addr, Rbase, Rcard_addr); // This is the address which needs to get enqueued. | 2342 add(Rcard_addr, Rbase, Rcard_addr); // This is the address which needs to get enqueued. |
2343 Rbase = noreg; // end of lifetime | 2343 Rbase = noreg; // end of lifetime |
2360 // Save the live input values. | 2360 // Save the live input values. |
2361 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), Rcard_addr, R16_thread); | 2361 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), Rcard_addr, R16_thread); |
2362 | 2362 |
2363 bind(filtered_int); | 2363 bind(filtered_int); |
2364 } | 2364 } |
2365 #endif // SERIALGC | 2365 #endif // INCLUDE_ALL_GCS |
2366 | 2366 |
2367 // Values for last_Java_pc, and last_Java_sp must comply to the rules | 2367 // Values for last_Java_pc, and last_Java_sp must comply to the rules |
2368 // in frame_ppc64.hpp. | 2368 // in frame_ppc64.hpp. |
2369 void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc) { | 2369 void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc) { |
2370 // Always set last_Java_pc and flags first because once last_Java_sp | 2370 // Always set last_Java_pc and flags first because once last_Java_sp |
2451 | 2451 |
2452 | 2452 |
2453 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { | 2453 void MacroAssembler::encode_klass_not_null(Register dst, Register src) { |
2454 Register current = (src != noreg) ? src : dst; // Klass is in dst if no src provided. | 2454 Register current = (src != noreg) ? src : dst; // Klass is in dst if no src provided. |
2455 if (Universe::narrow_klass_base() != 0) { | 2455 if (Universe::narrow_klass_base() != 0) { |
2456 load_const(R0, Universe::narrow_klass_base(), (dst != current) ? dst : noreg); // Use dst as temp if it is free. | 2456 // Use dst as temp if it is free. |
2457 load_const(R0, Universe::narrow_klass_base(), (dst != current && dst != R0) ? dst : noreg); | |
2457 sub(dst, current, R0); | 2458 sub(dst, current, R0); |
2458 current = dst; | 2459 current = dst; |
2459 } | 2460 } |
2460 if (Universe::narrow_klass_shift() != 0) { | 2461 if (Universe::narrow_klass_shift() != 0) { |
2461 srdi(dst, current, Universe::narrow_klass_shift()); | 2462 srdi(dst, current, Universe::narrow_klass_shift()); |