1 /* |
1 /* |
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
2865 // |
2865 // |
2866 // callee_saved_regs must include addr and count |
2866 // callee_saved_regs must include addr and count |
2867 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR) except for callee_saved_regs. |
2867 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR) except for callee_saved_regs. |
2868 void gen_write_ref_array_pre_barrier(Register addr, Register count, int callee_saved_regs) { |
2868 void gen_write_ref_array_pre_barrier(Register addr, Register count, int callee_saved_regs) { |
2869 BarrierSet* bs = Universe::heap()->barrier_set(); |
2869 BarrierSet* bs = Universe::heap()->barrier_set(); |
2870 if (bs->has_write_ref_pre_barrier()) { |
2870 switch (bs->kind()) { |
2871 assert(bs->has_write_ref_array_pre_opt(), |
2871 case BarrierSet::G1SATBCTLogging: |
2872 "Else unsupported barrier set."); |
2872 { |
2873 |
2873 assert( addr->encoding() < callee_saved_regs, "addr must be saved"); |
2874 assert( addr->encoding() < callee_saved_regs, "addr must be saved"); |
2874 assert(count->encoding() < callee_saved_regs, "count must be saved"); |
2875 assert(count->encoding() < callee_saved_regs, "count must be saved"); |
2875 |
2876 |
2876 BLOCK_COMMENT("PreBarrier"); |
2877 BLOCK_COMMENT("PreBarrier"); |
|
2878 |
2877 |
2879 #ifdef AARCH64 |
2878 #ifdef AARCH64 |
2880 callee_saved_regs = align_up(callee_saved_regs, 2); |
2879 callee_saved_regs = align_up(callee_saved_regs, 2); |
2881 for (int i = 0; i < callee_saved_regs; i += 2) { |
2880 for (int i = 0; i < callee_saved_regs; i += 2) { |
2882 __ raw_push(as_Register(i), as_Register(i+1)); |
2881 __ raw_push(as_Register(i), as_Register(i+1)); |
|
2882 } |
|
2883 #else |
|
2884 RegisterSet saved_regs = RegisterSet(R0, as_Register(callee_saved_regs-1)); |
|
2885 __ push(saved_regs | R9ifScratched); |
|
2886 #endif // AARCH64 |
|
2887 |
|
2888 if (addr != R0) { |
|
2889 assert_different_registers(count, R0); |
|
2890 __ mov(R0, addr); |
|
2891 } |
|
2892 #ifdef AARCH64 |
|
2893 __ zero_extend(R1, count, 32); // BarrierSet::static_write_ref_array_pre takes size_t |
|
2894 #else |
|
2895 if (count != R1) { |
|
2896 __ mov(R1, count); |
|
2897 } |
|
2898 #endif // AARCH64 |
|
2899 |
|
2900 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)); |
|
2901 |
|
2902 #ifdef AARCH64 |
|
2903 for (int i = callee_saved_regs - 2; i >= 0; i -= 2) { |
|
2904 __ raw_pop(as_Register(i), as_Register(i+1)); |
|
2905 } |
|
2906 #else |
|
2907 __ pop(saved_regs | R9ifScratched); |
|
2908 #endif // AARCH64 |
2883 } |
2909 } |
2884 #else |
2910 case BarrierSet::CardTableForRS: |
2885 RegisterSet saved_regs = RegisterSet(R0, as_Register(callee_saved_regs-1)); |
2911 case BarrierSet::CardTableExtension: |
2886 __ push(saved_regs | R9ifScratched); |
2912 break; |
2887 #endif // AARCH64 |
2913 default: |
2888 |
2914 ShouldNotReachHere(); |
2889 if (addr != R0) { |
|
2890 assert_different_registers(count, R0); |
|
2891 __ mov(R0, addr); |
|
2892 } |
|
2893 #ifdef AARCH64 |
|
2894 __ zero_extend(R1, count, 32); // BarrierSet::static_write_ref_array_pre takes size_t |
|
2895 #else |
|
2896 if (count != R1) { |
|
2897 __ mov(R1, count); |
|
2898 } |
|
2899 #endif // AARCH64 |
|
2900 |
|
2901 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre)); |
|
2902 |
|
2903 #ifdef AARCH64 |
|
2904 for (int i = callee_saved_regs - 2; i >= 0; i -= 2) { |
|
2905 __ raw_pop(as_Register(i), as_Register(i+1)); |
|
2906 } |
|
2907 #else |
|
2908 __ pop(saved_regs | R9ifScratched); |
|
2909 #endif // AARCH64 |
|
2910 } |
2915 } |
2911 } |
2916 } |
2912 #endif // INCLUDE_ALL_GCS |
2917 #endif // INCLUDE_ALL_GCS |
2913 |
2918 |
2914 // |
2919 // |