src/hotspot/cpu/arm/stubGenerator_arm.cpp
changeset 47658 c2b7fb8e5144
parent 47216 71c04702a3d5
child 48104 62d5973082e3
child 55767 8e22715afabc
equal deleted inserted replaced
47657:28b2dbe488f1 47658:c2b7fb8e5144
     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   //