< prev index next >

src/hotspot/cpu/arm/stubGenerator_arm.cpp

rename things

8  * This code is distributed in the hope that it will be useful, but WITHOUT                                                          
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or                                                             
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License                                                             
11  * version 2 for more details (a copy is included in the LICENSE file that                                                           
12  * accompanied this code).                                                                                                           
13  *                                                                                                                                   
14  * You should have received a copy of the GNU General Public License version                                                         
15  * 2 along with this work; if not, write to the Free Software Foundation,                                                            
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.                                                                     
17  *                                                                                                                                   
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA                                                           
19  * or visit www.oracle.com if you need additional information or have any                                                            
20  * questions.                                                                                                                        
21  *                                                                                                                                   
22  */                                                                                                                                  
23 
24 #include "precompiled.hpp"                                                                                                           
25 #include "asm/assembler.hpp"                                                                                                         
26 #include "assembler_arm.inline.hpp"                                                                                                  
27 #include "gc/shared/barrierSet.hpp"                                                                                                  
28 #include "gc/shared/barrierSetCodeGen.hpp"                                                                                           
29 #include "interpreter/interpreter.hpp"                                                                                               
30 #include "nativeInst_arm.hpp"                                                                                                        
31 #include "oops/instanceOop.hpp"                                                                                                      
32 #include "oops/method.hpp"                                                                                                           
33 #include "oops/objArrayKlass.hpp"                                                                                                    
34 #include "oops/oop.inline.hpp"                                                                                                       
35 #include "prims/methodHandles.hpp"                                                                                                   
36 #include "runtime/frame.inline.hpp"                                                                                                  
37 #include "runtime/handles.inline.hpp"                                                                                                
38 #include "runtime/sharedRuntime.hpp"                                                                                                 
39 #include "runtime/stubCodeGenerator.hpp"                                                                                             
40 #include "runtime/stubRoutines.hpp"                                                                                                  
41 #include "utilities/align.hpp"                                                                                                       
42 #ifdef COMPILER2                                                                                                                     
43 #include "opto/runtime.hpp"                                                                                                          
44 #endif                                                                                                                               
45 
46 // Declaration and definition of StubGenerator (no .hpp file).                                                                       
47 // For a more detailed description of the stub routine structure                                                                     

8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  *
22  */
23 
24 #include "precompiled.hpp"
25 #include "asm/assembler.hpp"
26 #include "assembler_arm.inline.hpp"
27 #include "gc/shared/barrierSet.hpp"
28 #include "gc/shared/barrierSetAssembler.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "nativeInst_arm.hpp"
31 #include "oops/instanceOop.hpp"
32 #include "oops/method.hpp"
33 #include "oops/objArrayKlass.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/methodHandles.hpp"
36 #include "runtime/frame.inline.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubCodeGenerator.hpp"
40 #include "runtime/stubRoutines.hpp"
41 #include "utilities/align.hpp"
42 #ifdef COMPILER2
43 #include "opto/runtime.hpp"
44 #endif
45 
46 // Declaration and definition of StubGenerator (no .hpp file).
47 // For a more detailed description of the stub routine structure

2858   // Generates pattern of code to be placed after raw data copying in generate_oop_copy                                              
2859   // Includes return from arraycopy stub.                                                                                            
2860   //                                                                                                                                 
2861   // Arguments:                                                                                                                      
2862   //     to:       destination pointer after copying.                                                                                
2863   //               if 'forward' then 'to' == upper bound, else 'to' == beginning of the modified region                              
2864   //     count:    total number of copied elements, 32-bit int                                                                       
2865   //                                                                                                                                 
2866   // Blows all volatile (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR) and 'to', 'count', 'tmp' registers.                      
2867   void oop_arraycopy_stub_epilogue_helper(Register to, Register count, Register tmp, bool status, bool forward, DecoratorSet decorato
2868     assert_different_registers(to, count, tmp);                                                                                      
2869 
2870     if (forward) {                                                                                                                   
2871       // 'to' is upper bound of the modified region                                                                                  
2872       // restore initial dst:                                                                                                        
2873       __ sub_ptr_scaled_int32(to, to, count, LogBytesPerHeapOop);                                                                    
2874     }                                                                                                                                
2875 
2876     // 'to' is the beginning of the region                                                                                           
2877 
2878     BarrierSet *bs = BarrierSet::barrier_set();                                                                                      
2879     BarrierSetCodeGen *code_gen = bs->code_gen();                                                                                    
2880     code_gen->arraycopy_epilogue(this, decorators, true, to, count, tmp);                                                            
2881 
2882     if (status) {                                                                                                                    
2883       __ mov(R0, 0); // OK                                                                                                           
2884     }                                                                                                                                
2885 
2886 #ifdef AARCH64                                                                                                                       
2887     __ raw_pop(LR, ZR);                                                                                                              
2888     __ ret();                                                                                                                        
2889 #else                                                                                                                                
2890     __ pop(PC);                                                                                                                      
2891 #endif // AARCH64                                                                                                                    
2892   }                                                                                                                                  
2893 
2894 
2895   //  Generate stub for assign-compatible oop copy.  If "aligned" is true, the                                                       
2896   //  "from" and "to" addresses are assumed to be heapword aligned.                                                                  
2897   //                                                                                                                                 
2898   //  If "disjoint" is true, arrays are assumed to be disjoint, otherwise they may overlap and                                       
2899   //  "nooverlap_target" must be specified as the address to jump if they don't.                                                     

2858   // Generates pattern of code to be placed after raw data copying in generate_oop_copy
2859   // Includes return from arraycopy stub.
2860   //
2861   // Arguments:
2862   //     to:       destination pointer after copying.
2863   //               if 'forward' then 'to' == upper bound, else 'to' == beginning of the modified region
2864   //     count:    total number of copied elements, 32-bit int
2865   //
2866   // Blows all volatile (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR) and 'to', 'count', 'tmp' registers.
2867   void oop_arraycopy_stub_epilogue_helper(Register to, Register count, Register tmp, bool status, bool forward, DecoratorSet decorato
2868     assert_different_registers(to, count, tmp);
2869 
2870     if (forward) {
2871       // 'to' is upper bound of the modified region
2872       // restore initial dst:
2873       __ sub_ptr_scaled_int32(to, to, count, LogBytesPerHeapOop);
2874     }
2875 
2876     // 'to' is the beginning of the region
2877 
2878     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2879     bs->arraycopy_epilogue(this, decorators, true, to, count, tmp);

2880 
2881     if (status) {
2882       __ mov(R0, 0); // OK
2883     }
2884 
2885 #ifdef AARCH64
2886     __ raw_pop(LR, ZR);
2887     __ ret();
2888 #else
2889     __ pop(PC);
2890 #endif // AARCH64
2891   }
2892 
2893 
2894   //  Generate stub for assign-compatible oop copy.  If "aligned" is true, the
2895   //  "from" and "to" addresses are assumed to be heapword aligned.
2896   //
2897   //  If "disjoint" is true, arrays are assumed to be disjoint, otherwise they may overlap and
2898   //  "nooverlap_target" must be specified as the address to jump if they don't.

2936     const int log_bytes_per_count = LogBytesPerHeapOop;                                                                              
2937 
2938     const Register saved_count = LR;                                                                                                 
2939     const int callee_saved_regs = 3; // R0-R2                                                                                        
2940 
2941     // LR is used later to save barrier args                                                                                         
2942 #ifdef AARCH64                                                                                                                       
2943     __ raw_push(LR, ZR);                                                                                                             
2944 #else                                                                                                                                
2945     __ push(LR);                                                                                                                     
2946 #endif // AARCH64                                                                                                                    
2947 
2948     DecoratorSet decorators = 0;                                                                                                     
2949     if (disjoint) {                                                                                                                  
2950       decorators |= ARRAYCOPY_DISJOINT;                                                                                              
2951     }                                                                                                                                
2952     if (aligned) {                                                                                                                   
2953       decorators |= ARRAYCOPY_ALIGNED;                                                                                               
2954     }                                                                                                                                
2955 
2956     BarrierSet *bs = BarrierSet::barrier_set();                                                                                      
2957     BarrierSetCodeGen *code_gen = bs->code_gen();                                                                                    
2958     code_gen->arraycopy_prologue(this, decorators, true, to, count, callee_saved_regs);                                              
2959 
2960     // save arguments for barrier generation (after the pre barrier)                                                                 
2961     __ mov(saved_count, count);                                                                                                      
2962 
2963     if (!forward) {                                                                                                                  
2964       __ add_ptr_scaled_int32(to,   to,   count, log_bytes_per_count);                                                               
2965       __ add_ptr_scaled_int32(from, from, count, log_bytes_per_count);                                                               
2966     }                                                                                                                                
2967 
2968     // for short arrays, just do single element copy                                                                                 
2969     Label L_small_array;                                                                                                             
2970     const int small_copy_limit = (8*wordSize + 7)/bytes_per_count; // XXX optim: tune the limit higher ?                             
2971     __ cmp_32(count, small_copy_limit);                                                                                              
2972     __ b(L_small_array, le);                                                                                                         
2973 
2974     bool from_is_aligned = (bytes_per_count >= 8);                                                                                   
2975     if (aligned && forward && (HeapWordSize % 8 == 0)) {                                                                             
2976         // if 'from' is heapword aligned and HeapWordSize is divisible by 8,                                                         
2977         //  then from is aligned by 8                                                                                                

2935     const int log_bytes_per_count = LogBytesPerHeapOop;
2936 
2937     const Register saved_count = LR;
2938     const int callee_saved_regs = 3; // R0-R2
2939 
2940     // LR is used later to save barrier args
2941 #ifdef AARCH64
2942     __ raw_push(LR, ZR);
2943 #else
2944     __ push(LR);
2945 #endif // AARCH64
2946 
2947     DecoratorSet decorators = 0;
2948     if (disjoint) {
2949       decorators |= ARRAYCOPY_DISJOINT;
2950     }
2951     if (aligned) {
2952       decorators |= ARRAYCOPY_ALIGNED;
2953     }
2954 
2955     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2956     bs->arraycopy_prologue(this, decorators, true, to, count, callee_saved_regs);

2957 
2958     // save arguments for barrier generation (after the pre barrier)
2959     __ mov(saved_count, count);
2960 
2961     if (!forward) {
2962       __ add_ptr_scaled_int32(to,   to,   count, log_bytes_per_count);
2963       __ add_ptr_scaled_int32(from, from, count, log_bytes_per_count);
2964     }
2965 
2966     // for short arrays, just do single element copy
2967     Label L_small_array;
2968     const int small_copy_limit = (8*wordSize + 7)/bytes_per_count; // XXX optim: tune the limit higher ?
2969     __ cmp_32(count, small_copy_limit);
2970     __ b(L_small_array, le);
2971 
2972     bool from_is_aligned = (bytes_per_count >= 8);
2973     if (aligned && forward && (HeapWordSize % 8 == 0)) {
2974         // if 'from' is heapword aligned and HeapWordSize is divisible by 8,
2975         //  then from is aligned by 8

3203 
3204     const int callee_saved_regs = AARCH64_ONLY(5) NOT_AARCH64(4); // LR saved differently                                            
3205 
3206     Label load_element, store_element, do_epilogue, fail;                                                                            
3207 
3208     BLOCK_COMMENT("Entry:");                                                                                                         
3209 
3210     __ zap_high_non_significant_bits(R2);                                                                                            
3211 
3212 #ifdef AARCH64                                                                                                                       
3213     __ raw_push(LR, ZR);                                                                                                             
3214     __ raw_push(R19, R20);                                                                                                           
3215 #else                                                                                                                                
3216     int pushed = 0;                                                                                                                  
3217     __ push(LR);                                                                                                                     
3218     pushed+=1;                                                                                                                       
3219 #endif // AARCH64                                                                                                                    
3220 
3221     DecoratorSet decorators = ARRAYCOPY_CHECKCAST;                                                                                   
3222 
3223     BarrierSet *bs = BarrierSet::barrier_set();                                                                                      
3224     BarrierSetCodeGen *code_gen = bs->code_gen();                                                                                    
3225     code_gen->arraycopy_prologue(this, decorators, true, to, count, callee_saved_regs);                                              
3226 
3227 #ifndef AARCH64                                                                                                                      
3228     const RegisterSet caller_saved_regs = RegisterSet(R4,R6) | RegisterSet(R8,R9) | altFP_7_11;                                      
3229     __ push(caller_saved_regs);                                                                                                      
3230     assert(caller_saved_regs.size() == 6, "check the count");                                                                        
3231     pushed+=6;                                                                                                                       
3232 
3233     __ ldr(R4_ckval,Address(SP, wordSize*pushed)); // read the argument that was on the stack                                        
3234 #endif // !AARCH64                                                                                                                   
3235 
3236     // Save arguments for barrier generation (after the pre barrier):                                                                
3237     // - must be a caller saved register and not LR                                                                                  
3238     // - ARM32: avoid R10 in case RThread is needed                                                                                  
3239     const Register saved_count = AARCH64_ONLY(R19) NOT_AARCH64(altFP_7_11);                                                          
3240 #ifdef AARCH64                                                                                                                       
3241     __ mov_w(saved_count, count);                                                                                                    
3242     __ cbnz_w(count, load_element); // and test count                                                                                
3243 #else                                                                                                                                
3244     __ movs(saved_count, count); // and test count                                                                                   

3201 
3202     const int callee_saved_regs = AARCH64_ONLY(5) NOT_AARCH64(4); // LR saved differently
3203 
3204     Label load_element, store_element, do_epilogue, fail;
3205 
3206     BLOCK_COMMENT("Entry:");
3207 
3208     __ zap_high_non_significant_bits(R2);
3209 
3210 #ifdef AARCH64
3211     __ raw_push(LR, ZR);
3212     __ raw_push(R19, R20);
3213 #else
3214     int pushed = 0;
3215     __ push(LR);
3216     pushed+=1;
3217 #endif // AARCH64
3218 
3219     DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
3220 
3221     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
3222     bs->arraycopy_prologue(this, decorators, true, to, count, callee_saved_regs);

3223 
3224 #ifndef AARCH64
3225     const RegisterSet caller_saved_regs = RegisterSet(R4,R6) | RegisterSet(R8,R9) | altFP_7_11;
3226     __ push(caller_saved_regs);
3227     assert(caller_saved_regs.size() == 6, "check the count");
3228     pushed+=6;
3229 
3230     __ ldr(R4_ckval,Address(SP, wordSize*pushed)); // read the argument that was on the stack
3231 #endif // !AARCH64
3232 
3233     // Save arguments for barrier generation (after the pre barrier):
3234     // - must be a caller saved register and not LR
3235     // - ARM32: avoid R10 in case RThread is needed
3236     const Register saved_count = AARCH64_ONLY(R19) NOT_AARCH64(altFP_7_11);
3237 #ifdef AARCH64
3238     __ mov_w(saved_count, count);
3239     __ cbnz_w(count, load_element); // and test count
3240 #else
3241     __ movs(saved_count, count); // and test count

3283     // ======== end loop ========                                                                                                    
3284 
3285     // It was a real error; we must depend on the caller to finish the job.                                                          
3286     // Register count has number of *remaining* oops, saved_count number of *total* oops.                                            
3287     // Emit GC store barriers for the oops we have copied                                                                            
3288     // and report their number to the caller (0 or (-1^n))                                                                           
3289     __ BIND(fail);                                                                                                                   
3290 
3291     // Note: fail marked by the fact that count differs from saved_count                                                             
3292 
3293     __ BIND(do_epilogue);                                                                                                            
3294 
3295     Register copied = AARCH64_ONLY(R20) NOT_AARCH64(R4); // saved                                                                    
3296     Label L_not_copied;                                                                                                              
3297 
3298     __ subs_32(copied, saved_count, count); // copied count (in saved reg)                                                           
3299     __ b(L_not_copied, eq); // nothing was copied, skip post barrier                                                                 
3300     __ sub(to, to, AsmOperand(copied, lsl, LogBytesPerHeapOop)); // initial to value                                                 
3301     __ mov(R12, copied); // count arg scratched by post barrier                                                                      
3302 
3303     code_gen->arraycopy_epilogue(this, decorators, true, to, R12, R3);                                                               
3304 
3305     assert_different_registers(R3,R12,LR,copied,saved_count);                                                                        
3306     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R3, R12);                                                               
3307 
3308     __ BIND(L_not_copied);                                                                                                           
3309     __ cmp_32(copied, saved_count); // values preserved in saved registers                                                           
3310 
3311 #ifdef AARCH64                                                                                                                       
3312     __ csinv(R0, ZR, copied, eq); // 0 if all copied else NOT(copied)                                                                
3313     __ raw_pop(R19, R20);                                                                                                            
3314     __ raw_pop(LR, ZR);                                                                                                              
3315     __ ret();                                                                                                                        
3316 #else                                                                                                                                
3317     __ mov(R0, 0, eq); // 0 if all copied                                                                                            
3318     __ mvn(R0, copied, ne); // else NOT(copied)                                                                                      
3319     __ pop(caller_saved_regs);                                                                                                       
3320     __ pop(PC);                                                                                                                      
3321 #endif // AARCH64                                                                                                                    
3322 

3280     // ======== end loop ========
3281 
3282     // It was a real error; we must depend on the caller to finish the job.
3283     // Register count has number of *remaining* oops, saved_count number of *total* oops.
3284     // Emit GC store barriers for the oops we have copied
3285     // and report their number to the caller (0 or (-1^n))
3286     __ BIND(fail);
3287 
3288     // Note: fail marked by the fact that count differs from saved_count
3289 
3290     __ BIND(do_epilogue);
3291 
3292     Register copied = AARCH64_ONLY(R20) NOT_AARCH64(R4); // saved
3293     Label L_not_copied;
3294 
3295     __ subs_32(copied, saved_count, count); // copied count (in saved reg)
3296     __ b(L_not_copied, eq); // nothing was copied, skip post barrier
3297     __ sub(to, to, AsmOperand(copied, lsl, LogBytesPerHeapOop)); // initial to value
3298     __ mov(R12, copied); // count arg scratched by post barrier
3299 
3300     bs->arraycopy_epilogue(this, decorators, true, to, R12, R3);
3301 
3302     assert_different_registers(R3,R12,LR,copied,saved_count);
3303     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, R3, R12);
3304 
3305     __ BIND(L_not_copied);
3306     __ cmp_32(copied, saved_count); // values preserved in saved registers
3307 
3308 #ifdef AARCH64
3309     __ csinv(R0, ZR, copied, eq); // 0 if all copied else NOT(copied)
3310     __ raw_pop(R19, R20);
3311     __ raw_pop(LR, ZR);
3312     __ ret();
3313 #else
3314     __ mov(R0, 0, eq); // 0 if all copied
3315     __ mvn(R0, copied, ne); // else NOT(copied)
3316     __ pop(caller_saved_regs);
3317     __ pop(PC);
3318 #endif // AARCH64
3319 
< prev index next >