< prev index next >

src/hotspot/cpu/sparc/stubGenerator_sparc.cpp

8198949_arraycopy

rename things

6  * published by the Free Software Foundation.                                                                                        
7  *                                                                                                                                   
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/macroAssembler.inline.hpp"                                                                                             
26 #include "gc/shared/cardTable.hpp"                                                                                                   
27 #include "gc/shared/cardTableBarrierSet.hpp"                                                                                         
28 #include "interpreter/interpreter.hpp"                                                                                               
29 #include "nativeInst_sparc.hpp"                                                                                                      
30 #include "oops/instanceOop.hpp"                                                                                                      
31 #include "oops/method.hpp"                                                                                                           
32 #include "oops/objArrayKlass.hpp"                                                                                                    
33 #include "oops/oop.inline.hpp"                                                                                                       
34 #include "prims/methodHandles.hpp"                                                                                                   
35 #include "runtime/frame.inline.hpp"                                                                                                  
36 #include "runtime/handles.inline.hpp"                                                                                                
37 #include "runtime/sharedRuntime.hpp"                                                                                                 
38 #include "runtime/stubCodeGenerator.hpp"                                                                                             
39 #include "runtime/stubRoutines.hpp"                                                                                                  
40 #include "runtime/thread.inline.hpp"                                                                                                 
41 #ifdef COMPILER2                                                                                                                     
42 #include "opto/runtime.hpp"                                                                                                          
43 #endif                                                                                                                               
44 
45 // Declaration and definition of StubGenerator (no .hpp file).                                                                       
46 // For a more detailed description of the stub routine structure                                                                     

6  * published by the Free Software Foundation.
7  *
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/macroAssembler.inline.hpp"
26 #include "gc/shared/barrierSet.hpp"
27 #include "gc/shared/barrierSetAssembler.hpp"
28 #include "interpreter/interpreter.hpp"
29 #include "nativeInst_sparc.hpp"
30 #include "oops/instanceOop.hpp"
31 #include "oops/method.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/methodHandles.hpp"
35 #include "runtime/frame.inline.hpp"
36 #include "runtime/handles.inline.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #include "runtime/stubCodeGenerator.hpp"
39 #include "runtime/stubRoutines.hpp"
40 #include "runtime/thread.inline.hpp"
41 #ifdef COMPILER2
42 #include "opto/runtime.hpp"
43 #endif
44 
45 // Declaration and definition of StubGenerator (no .hpp file).
46 // For a more detailed description of the stub routine structure

805     const Register from       = O0;                                                                                                  
806     const Register to         = O1;                                                                                                  
807     const Register count      = O2;                                                                                                  
808     const Register to_from    = O3; // to - from                                                                                     
809     const Register byte_count = O4; // count << log2_elem_size                                                                       
810 
811       __ subcc(to, from, to_from);                                                                                                   
812       __ sll_ptr(count, log2_elem_size, byte_count);                                                                                 
813       if (NOLp == NULL)                                                                                                              
814         __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, no_overlap_target);                                               
815       else                                                                                                                           
816         __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, (*NOLp));                                                         
817       __ delayed()->cmp(to_from, byte_count);                                                                                        
818       if (NOLp == NULL)                                                                                                              
819         __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, no_overlap_target);                                            
820       else                                                                                                                           
821         __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, (*NOLp));                                                      
822       __ delayed()->nop();                                                                                                           
823   }                                                                                                                                  
824 
825   //                                                                                                                                 
826   //  Generate pre-write barrier for array.                                                                                          
827   //                                                                                                                                 
828   //  Input:                                                                                                                         
829   //     addr     - register containing starting address                                                                             
830   //     count    - register containing element count                                                                                
831   //     tmp      - scratch register                                                                                                 
832   //                                                                                                                                 
833   //  The input registers are overwritten.                                                                                           
834   //                                                                                                                                 
835   void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {                                     
836     BarrierSet* bs = Universe::heap()->barrier_set();                                                                                
837     switch (bs->kind()) {                                                                                                            
838       case BarrierSet::G1BarrierSet:                                                                                                 
839         // With G1, don't generate the call if we statically know that the target in uninitialized                                   
840         if (!dest_uninitialized) {                                                                                                   
841           Register tmp = O5;                                                                                                         
842           assert_different_registers(addr, count, tmp);                                                                              
843           Label filtered;                                                                                                            
844           // Is marking active?                                                                                                      
845           if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {                                                                
846             __ ld(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);                 
847           } else {                                                                                                                   
848             guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,                                                          
849                       "Assumption");                                                                                                 
850             __ ldsb(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);               
851           }                                                                                                                          
852           // Is marking active?                                                                                                      
853           __ cmp_and_br_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);                                                   
854                                                                                                                                      
855           __ save_frame(0);                                                                                                          
856           // Save the necessary global regs... will be used after.                                                                   
857           if (addr->is_global()) {                                                                                                   
858             __ mov(addr, L0);                                                                                                        
859           }                                                                                                                          
860           if (count->is_global()) {                                                                                                  
861             __ mov(count, L1);                                                                                                       
862           }                                                                                                                          
863           __ mov(addr->after_save(), O0);                                                                                            
864           // Get the count into O1                                                                                                   
865           __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));                                                
866           __ delayed()->mov(count->after_save(), O1);                                                                                
867           if (addr->is_global()) {                                                                                                   
868             __ mov(L0, addr);                                                                                                        
869           }                                                                                                                          
870           if (count->is_global()) {                                                                                                  
871             __ mov(L1, count);                                                                                                       
872           }                                                                                                                          
873           __ restore();                                                                                                              
874                                                                                                                                      
875           __ bind(filtered);                                                                                                         
876           DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp                                                                 
877         }                                                                                                                            
878         break;                                                                                                                       
879       case BarrierSet::CardTableBarrierSet:                                                                                          
880         break;                                                                                                                       
881       default:                                                                                                                       
882         ShouldNotReachHere();                                                                                                        
883     }                                                                                                                                
884   }                                                                                                                                  
885   //                                                                                                                                 
886   //  Generate post-write barrier for array.                                                                                         
887   //                                                                                                                                 
888   //  Input:                                                                                                                         
889   //     addr     - register containing starting address                                                                             
890   //     count    - register containing element count                                                                                
891   //     tmp      - scratch register                                                                                                 
892   //                                                                                                                                 
893   //  The input registers are overwritten.                                                                                           
894   //                                                                                                                                 
895   void gen_write_ref_array_post_barrier(Register addr, Register count,                                                               
896                                         Register tmp) {                                                                              
897     BarrierSet* bs = Universe::heap()->barrier_set();                                                                                
898                                                                                                                                      
899     switch (bs->kind()) {                                                                                                            
900       case BarrierSet::G1BarrierSet:                                                                                                 
901         {                                                                                                                            
902           // Get some new fresh output registers.                                                                                    
903           __ save_frame(0);                                                                                                          
904           __ mov(addr->after_save(), O0);                                                                                            
905           __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post));                                               
906           __ delayed()->mov(count->after_save(), O1);                                                                                
907           __ restore();                                                                                                              
908         }                                                                                                                            
909         break;                                                                                                                       
910       case BarrierSet::CardTableBarrierSet:                                                                                          
911         {                                                                                                                            
912           CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);                                                     
913           CardTable* ct = ctbs->card_table();                                                                                        
914           assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");                                                 
915           assert_different_registers(addr, count, tmp);                                                                              
916                                                                                                                                      
917           Label L_loop, L_done;                                                                                                      
918                                                                                                                                      
919           __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do                      
920                                                                                                                                      
921           __ sll_ptr(count, LogBytesPerHeapOop, count);                                                                              
922           __ sub(count, BytesPerHeapOop, count);                                                                                     
923           __ add(count, addr, count);                                                                                                
924           // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)                                             
925           __ srl_ptr(addr, CardTable::card_shift, addr);                                                                             
926           __ srl_ptr(count, CardTable::card_shift, count);                                                                           
927           __ sub(count, addr, count);                                                                                                
928           AddressLiteral rs(ct->byte_map_base());                                                                                    
929           __ set(rs, tmp);                                                                                                           
930         __ BIND(L_loop);                                                                                                             
931           __ stb(G0, tmp, addr);                                                                                                     
932           __ subcc(count, 1, count);                                                                                                 
933           __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);                                                             
934           __ delayed()->add(addr, 1, addr);                                                                                          
935         __ BIND(L_done);                                                                                                             
936         }                                                                                                                            
937         break;                                                                                                                       
938       case BarrierSet::ModRef:                                                                                                       
939         break;                                                                                                                       
940       default:                                                                                                                       
941         ShouldNotReachHere();                                                                                                        
942     }                                                                                                                                
943   }                                                                                                                                  
944 
945   //                                                                                                                                 
946   // Generate main code for disjoint arraycopy                                                                                       
947   //                                                                                                                                 
948   typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,                             
949                                               Label& L_loop, bool use_prefetch, bool use_bis);                                       
950 
951   void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size,                                            
952                           int iter_size, StubGenerator::CopyLoopFunc copy_loop_func) {                                               
953     Label L_copy;                                                                                                                    
954 
955     assert(log2_elem_size <= 3, "the following code should be changed");                                                             
956     int count_dec = 16>>log2_elem_size;                                                                                              
957 
958     int prefetch_dist = MAX2(ArraycopySrcPrefetchDistance, ArraycopyDstPrefetchDistance);                                            
959     assert(prefetch_dist < 4096, "invalid value");                                                                                   
960     prefetch_dist = (prefetch_dist + (iter_size-1)) & (-iter_size); // round up to one iteration copy size                           
961     int prefetch_count = (prefetch_dist >> log2_elem_size); // elements count                                                        
962 

805     const Register from       = O0;
806     const Register to         = O1;
807     const Register count      = O2;
808     const Register to_from    = O3; // to - from
809     const Register byte_count = O4; // count << log2_elem_size
810 
811       __ subcc(to, from, to_from);
812       __ sll_ptr(count, log2_elem_size, byte_count);
813       if (NOLp == NULL)
814         __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, no_overlap_target);
815       else
816         __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, (*NOLp));
817       __ delayed()->cmp(to_from, byte_count);
818       if (NOLp == NULL)
819         __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, no_overlap_target);
820       else
821         __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, (*NOLp));
822       __ delayed()->nop();
823   }
824 























































































































825 
826   //
827   // Generate main code for disjoint arraycopy
828   //
829   typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,
830                                               Label& L_loop, bool use_prefetch, bool use_bis);
831 
832   void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size,
833                           int iter_size, StubGenerator::CopyLoopFunc copy_loop_func) {
834     Label L_copy;
835 
836     assert(log2_elem_size <= 3, "the following code should be changed");
837     int count_dec = 16>>log2_elem_size;
838 
839     int prefetch_dist = MAX2(ArraycopySrcPrefetchDistance, ArraycopyDstPrefetchDistance);
840     assert(prefetch_dist < 4096, "invalid value");
841     prefetch_dist = (prefetch_dist + (iter_size-1)) & (-iter_size); // round up to one iteration copy size
842     int prefetch_count = (prefetch_dist >> log2_elem_size); // elements count
843 

2370   //                                                                                                                                 
2371   address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name,                                                 
2372                                      bool dest_uninitialized = false) {                                                              
2373 
2374     const Register from  = O0;  // source array address                                                                              
2375     const Register to    = O1;  // destination array address                                                                         
2376     const Register count = O2;  // elements count                                                                                    
2377 
2378     __ align(CodeEntryAlignment);                                                                                                    
2379     StubCodeMark mark(this, "StubRoutines", name);                                                                                   
2380     address start = __ pc();                                                                                                         
2381 
2382     assert_clean_int(count, O3);     // Make sure 'count' is clean int.                                                              
2383 
2384     if (entry != NULL) {                                                                                                             
2385       *entry = __ pc();                                                                                                              
2386       // caller can pass a 64-bit byte count here                                                                                    
2387       BLOCK_COMMENT("Entry:");                                                                                                       
2388     }                                                                                                                                
2389 
2390     // save arguments for barrier generation                                                                                         
2391     __ mov(to, G1);                                                                                                                  
2392     __ mov(count, G5);                                                                                                               
2393     gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
2394     assert_clean_int(count, O3);     // Make sure 'count' is clean int.                                                              
2395     if (UseCompressedOops) {                                                                                                         
2396       generate_disjoint_int_copy_core(aligned);                                                                                      
2397     } else {                                                                                                                         
2398       generate_disjoint_long_copy_core(aligned);                                                                                     
2399     }                                                                                                                                
2400     // O0 is used as temp register                                                                                                   
2401     gen_write_ref_array_post_barrier(G1, G5, O0);                                                                                    
2402 
2403     // O3, O4 are used as temp registers                                                                                             
2404     inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);                                                                      
2405     __ retl();                                                                                                                       
2406     __ delayed()->mov(G0, O0); // return 0                                                                                           
2407     return start;                                                                                                                    
2408   }                                                                                                                                  
2409 
2410   //  Generate stub for conjoint oop copy.  If "aligned" is true, the                                                                
2411   //  "from" and "to" addresses are assumed to be heapword aligned.                                                                  
2412   //                                                                                                                                 
2413   // Arguments for generated stub:                                                                                                   
2414   //      from:  O0                                                                                                                  
2415   //      to:    O1                                                                                                                  
2416   //      count: O2 treated as signed                                                                                                
2417   //                                                                                                                                 
2418   address generate_conjoint_oop_copy(bool aligned, address nooverlap_target,                                                         
2419                                      address *entry, const char *name,                                                               
2420                                      bool dest_uninitialized = false) {                                                              
2421 
2422     const Register from  = O0;  // source array address                                                                              
2423     const Register to    = O1;  // destination array address                                                                         
2424     const Register count = O2;  // elements count                                                                                    
2425 
2426     __ align(CodeEntryAlignment);                                                                                                    
2427     StubCodeMark mark(this, "StubRoutines", name);                                                                                   
2428     address start = __ pc();                                                                                                         
2429 
2430     assert_clean_int(count, O3);     // Make sure 'count' is clean int.                                                              
2431 
2432     if (entry != NULL) {                                                                                                             
2433       *entry = __ pc();                                                                                                              
2434       // caller can pass a 64-bit byte count here                                                                                    
2435       BLOCK_COMMENT("Entry:");                                                                                                       
2436     }                                                                                                                                
2437 
2438     array_overlap_test(nooverlap_target, LogBytesPerHeapOop);                                                                        
2439 
2440     // save arguments for barrier generation                                                                                         
2441     __ mov(to, G1);                                                                                                                  
2442     __ mov(count, G5);                                                                                                               
2443     gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
2444 
2445     if (UseCompressedOops) {                                                                                                         
2446       generate_conjoint_int_copy_core(aligned);                                                                                      
2447     } else {                                                                                                                         
2448       generate_conjoint_long_copy_core(aligned);                                                                                     
2449     }                                                                                                                                
2450 
2451     // O0 is used as temp register                                                                                                   
2452     gen_write_ref_array_post_barrier(G1, G5, O0);                                                                                    
2453 
2454     // O3, O4 are used as temp registers                                                                                             
2455     inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);                                                                      
2456     __ retl();                                                                                                                       
2457     __ delayed()->mov(G0, O0); // return 0                                                                                           
2458     return start;                                                                                                                    
2459   }                                                                                                                                  
2460 
2461 
2462   // Helper for generating a dynamic type check.                                                                                     
2463   // Smashes only the given temp registers.                                                                                          
2464   void generate_type_check(Register sub_klass,                                                                                       
2465                            Register super_check_offset,                                                                              
2466                            Register super_klass,                                                                                     
2467                            Register temp,                                                                                            
2468                            Label& L_success) {                                                                                       
2469     assert_different_registers(sub_klass, super_check_offset, super_klass, temp);                                                    
2470 
2471     BLOCK_COMMENT("type_check:");                                                                                                    

2251   //
2252   address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name,
2253                                      bool dest_uninitialized = false) {
2254 
2255     const Register from  = O0;  // source array address
2256     const Register to    = O1;  // destination array address
2257     const Register count = O2;  // elements count
2258 
2259     __ align(CodeEntryAlignment);
2260     StubCodeMark mark(this, "StubRoutines", name);
2261     address start = __ pc();
2262 
2263     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2264 
2265     if (entry != NULL) {
2266       *entry = __ pc();
2267       // caller can pass a 64-bit byte count here
2268       BLOCK_COMMENT("Entry:");
2269     }
2270 
2271     DecoratorSet decorators = ARRAYCOPY_DISJOINT;
2272     if (dest_uninitialized) {
2273       decorators |= AS_DEST_NOT_INITIALIZED;
2274     }
2275     if (aligned) {
2276       decorators |= ARRAYCOPY_ALIGNED;
2277     }
2278 
2279     BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
2280     bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
2281 
2282     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2283     if (UseCompressedOops) {
2284       generate_disjoint_int_copy_core(aligned);
2285     } else {
2286       generate_disjoint_long_copy_core(aligned);
2287     }
2288 
2289     bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, from, to, count);
2290 
2291     // O3, O4 are used as temp registers
2292     inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);
2293     __ retl();
2294     __ delayed()->mov(G0, O0); // return 0
2295     return start;
2296   }
2297 
2298   //  Generate stub for conjoint oop copy.  If "aligned" is true, the
2299   //  "from" and "to" addresses are assumed to be heapword aligned.
2300   //
2301   // Arguments for generated stub:
2302   //      from:  O0
2303   //      to:    O1
2304   //      count: O2 treated as signed
2305   //
2306   address generate_conjoint_oop_copy(bool aligned, address nooverlap_target,
2307                                      address *entry, const char *name,
2308                                      bool dest_uninitialized = false) {
2309 
2310     const Register from  = O0;  // source array address
2311     const Register to    = O1;  // destination array address
2312     const Register count = O2;  // elements count
2313 
2314     __ align(CodeEntryAlignment);
2315     StubCodeMark mark(this, "StubRoutines", name);
2316     address start = __ pc();
2317 
2318     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
2319 
2320     if (entry != NULL) {
2321       *entry = __ pc();
2322       // caller can pass a 64-bit byte count here
2323       BLOCK_COMMENT("Entry:");
2324     }
2325 
2326     array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
2327 
2328     DecoratorSet decorators = 0;
2329     if (dest_uninitialized) {
2330       decorators |= AS_DEST_NOT_INITIALIZED;
2331     }
2332     if (aligned) {
2333       decorators |= ARRAYCOPY_ALIGNED;
2334     }
2335 
2336     BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
2337     bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
2338 
2339     if (UseCompressedOops) {
2340       generate_conjoint_int_copy_core(aligned);
2341     } else {
2342       generate_conjoint_long_copy_core(aligned);
2343     }
2344 
2345     bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, from, to, count);

2346 
2347     // O3, O4 are used as temp registers
2348     inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);
2349     __ retl();
2350     __ delayed()->mov(G0, O0); // return 0
2351     return start;
2352   }
2353 
2354 
2355   // Helper for generating a dynamic type check.
2356   // Smashes only the given temp registers.
2357   void generate_type_check(Register sub_klass,
2358                            Register super_check_offset,
2359                            Register super_klass,
2360                            Register temp,
2361                            Label& L_success) {
2362     assert_different_registers(sub_klass, super_check_offset, super_klass, temp);
2363 
2364     BLOCK_COMMENT("type_check:");

2534 
2535 #ifdef ASSERT                                                                                                                        
2536     // caller guarantees that the arrays really are different                                                                        
2537     // otherwise, we would have to make conjoint checks                                                                              
2538     { Label L;                                                                                                                       
2539       __ mov(O3, G1);           // spill: overlap test smashes O3                                                                    
2540       __ mov(O4, G4);           // spill: overlap test smashes O4                                                                    
2541       array_overlap_test(L, LogBytesPerHeapOop);                                                                                     
2542       __ stop("checkcast_copy within a single array");                                                                               
2543       __ bind(L);                                                                                                                    
2544       __ mov(G1, O3);                                                                                                                
2545       __ mov(G4, O4);                                                                                                                
2546     }                                                                                                                                
2547 #endif //ASSERT                                                                                                                      
2548 
2549     if (entry != NULL) {                                                                                                             
2550       *entry = __ pc();                                                                                                              
2551       // caller can pass a 64-bit byte count here (from generic stub)                                                                
2552       BLOCK_COMMENT("Entry:");                                                                                                       
2553     }                                                                                                                                
2554     gen_write_ref_array_pre_barrier(O1_to, O2_count, dest_uninitialized);                                                            
2555 
2556     Label load_element, store_element, do_card_marks, fail, done;                                                                    
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
2557     __ addcc(O2_count, 0, G1_remain);   // initialize loop index, and test it                                                        
2558     __ brx(Assembler::notZero, false, Assembler::pt, load_element);                                                                  
2559     __ delayed()->mov(G0, O5_offset);   // offset from start of arrays                                                               
2560 
2561     // Empty array:  Nothing to do.                                                                                                  
2562     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);                                                                
2563     __ retl();                                                                                                                       
2564     __ delayed()->set(0, O0);           // return 0 on (trivial) success                                                             
2565 
2566     // ======== begin loop ========                                                                                                  
2567     // (Loop is rotated; its entry is load_element.)                                                                                 
2568     // Loop variables:                                                                                                               
2569     //   (O5 = 0; ; O5 += wordSize) --- offset from src, dest arrays                                                                 
2570     //   (O2 = len; O2 != 0; O2--) --- number of oops *remaining*                                                                    
2571     //   G3, G4, G5 --- current oop, oop.klass, oop.klass.super                                                                      
2572     __ align(OptoLoopAlignment);                                                                                                     
2573 
2574     __ BIND(store_element);                                                                                                          
2575     __ deccc(G1_remain);                // decrement the count                                                                       
2576     __ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop                                                                    
2577     __ inc(O5_offset, heapOopSize);     // step to next offset                                                                       
2578     __ brx(Assembler::zero, true, Assembler::pt, do_card_marks);                                                                     
2579     __ delayed()->set(0, O0);           // return -1 on success                                                                      
2580 
2581     // ======== loop entry is here ========                                                                                          
2582     __ BIND(load_element);                                                                                                           
2583     __ load_heap_oop(O0_from, O5_offset, G3_oop);  // load the oop                                                                   
2584     __ br_null_short(G3_oop, Assembler::pt, store_element);                                                                          
2585 
2586     __ load_klass(G3_oop, G4_klass); // query the object klass                                                                       
2587 
2588     generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super,                                                                      
2589                         // branch to this on success:                                                                                
2590                         store_element);                                                                                              
2591     // ======== end loop ========                                                                                                    
2592 
2593     // It was a real error; we must depend on the caller to finish the job.                                                          
2594     // Register G1 has number of *remaining* oops, O2 number of *total* oops.                                                        
2595     // Emit GC store barriers for the oops we have copied (O2 minus G1),                                                             
2596     // and report their number to the caller.                                                                                        
2597     __ BIND(fail);                                                                                                                   
2598     __ subcc(O2_count, G1_remain, O2_count);                                                                                         
2599     __ brx(Assembler::zero, false, Assembler::pt, done);                                                                             
2600     __ delayed()->not1(O2_count, O0);   // report (-1^K) to caller                                                                   
2601 
2602     __ BIND(do_card_marks);                                                                                                          
2603     gen_write_ref_array_post_barrier(O1_to, O2_count, O3);   // store check on O1[0..O2]                                             
2604 
2605     __ BIND(done);                                                                                                                   
2606     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);                                                                
2607     __ retl();                                                                                                                       
2608     __ delayed()->nop();             // return value in 00                                                                           
2609 
2610     return start;                                                                                                                    
2611   }                                                                                                                                  
2612 
2613 
2614   //  Generate 'unsafe' array copy stub                                                                                              
2615   //  Though just as safe as the other stubs, it takes an unscaled                                                                   
2616   //  size_t argument instead of an element count.                                                                                   
2617   //                                                                                                                                 
2618   // Arguments for generated stub:                                                                                                   
2619   //      from:  O0                                                                                                                  
2620   //      to:    O1                                                                                                                  
2621   //      count: O2 byte count, treated as ssize_t, can be zero                                                                      
2622   //                                                                                                                                 

2427 
2428 #ifdef ASSERT
2429     // caller guarantees that the arrays really are different
2430     // otherwise, we would have to make conjoint checks
2431     { Label L;
2432       __ mov(O3, G1);           // spill: overlap test smashes O3
2433       __ mov(O4, G4);           // spill: overlap test smashes O4
2434       array_overlap_test(L, LogBytesPerHeapOop);
2435       __ stop("checkcast_copy within a single array");
2436       __ bind(L);
2437       __ mov(G1, O3);
2438       __ mov(G4, O4);
2439     }
2440 #endif //ASSERT
2441 
2442     if (entry != NULL) {
2443       *entry = __ pc();
2444       // caller can pass a 64-bit byte count here (from generic stub)
2445       BLOCK_COMMENT("Entry:");
2446     }

2447 
2448     DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
2449     if (dest_uninitialized) {
2450       decorators |= AS_DEST_NOT_INITIALIZED;
2451     }
2452 
2453     BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
2454     bs->arraycopy_prologue(_masm, decorators, T_OBJECT, O0_from, O1_to, O2_count);
2455 
2456     Label load_element, store_element, do_epilogue, fail, done;
2457     __ addcc(O2_count, 0, G1_remain);   // initialize loop index, and test it
2458     __ brx(Assembler::notZero, false, Assembler::pt, load_element);
2459     __ delayed()->mov(G0, O5_offset);   // offset from start of arrays
2460 
2461     // Empty array:  Nothing to do.
2462     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);
2463     __ retl();
2464     __ delayed()->set(0, O0);           // return 0 on (trivial) success
2465 
2466     // ======== begin loop ========
2467     // (Loop is rotated; its entry is load_element.)
2468     // Loop variables:
2469     //   (O5 = 0; ; O5 += wordSize) --- offset from src, dest arrays
2470     //   (O2 = len; O2 != 0; O2--) --- number of oops *remaining*
2471     //   G3, G4, G5 --- current oop, oop.klass, oop.klass.super
2472     __ align(OptoLoopAlignment);
2473 
2474     __ BIND(store_element);
2475     __ deccc(G1_remain);                // decrement the count
2476     __ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop
2477     __ inc(O5_offset, heapOopSize);     // step to next offset
2478     __ brx(Assembler::zero, true, Assembler::pt, do_epilogue);
2479     __ delayed()->set(0, O0);           // return -1 on success
2480 
2481     // ======== loop entry is here ========
2482     __ BIND(load_element);
2483     __ load_heap_oop(O0_from, O5_offset, G3_oop);  // load the oop
2484     __ br_null_short(G3_oop, Assembler::pt, store_element);
2485 
2486     __ load_klass(G3_oop, G4_klass); // query the object klass
2487 
2488     generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super,
2489                         // branch to this on success:
2490                         store_element);
2491     // ======== end loop ========
2492 
2493     // It was a real error; we must depend on the caller to finish the job.
2494     // Register G1 has number of *remaining* oops, O2 number of *total* oops.
2495     // Emit GC store barriers for the oops we have copied (O2 minus G1),
2496     // and report their number to the caller.
2497     __ BIND(fail);
2498     __ subcc(O2_count, G1_remain, O2_count);
2499     __ brx(Assembler::zero, false, Assembler::pt, done);
2500     __ delayed()->not1(O2_count, O0);   // report (-1^K) to caller
2501 
2502     __ BIND(do_epilogue);
2503     bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, O0_from, O1_to, O2_count);
2504 
2505     __ BIND(done);
2506     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);
2507     __ retl();
2508     __ delayed()->nop();             // return value in 00
2509 
2510     return start;
2511   }
2512 
2513 
2514   //  Generate 'unsafe' array copy stub
2515   //  Though just as safe as the other stubs, it takes an unscaled
2516   //  size_t argument instead of an element count.
2517   //
2518   // Arguments for generated stub:
2519   //      from:  O0
2520   //      to:    O1
2521   //      count: O2 byte count, treated as ssize_t, can be zero
2522   //
< prev index next >