< prev index next >

src/cpu/sparc/vm/templateTable_sparc.cpp

Print this page




2932     __ load_receiver(temp, recv);  //  __ argument_address uses Gargs but we need Lesp
2933     __ verify_oop(recv);
2934   }
2935 
2936   // compute return type
2937   __ srl(flags, ConstantPoolCacheEntry::tos_state_shift, ra);
2938   // Make sure we don't need to mask flags after the above shift
2939   ConstantPoolCacheEntry::verify_tos_state_shift();
2940   // load return address
2941   {
2942     const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
2943     AddressLiteral table(table_addr);
2944     __ set(table, temp);
2945     __ sll(ra, LogBytesPerWord, ra);
2946     __ ld_ptr(Address(temp, ra), ra);
2947   }
2948 }
2949 
2950 
2951 void TemplateTable::generate_vtable_call(Register Rrecv, Register Rindex, Register Rret) {

2952   Register Rcall = Rindex;
2953   assert_different_registers(Rcall, G5_method, Gargs, Rret);
2954 
2955   // get target Method* & entry point
2956   __ lookup_virtual_method(Rrecv, Rindex, G5_method);
2957   __ profile_arguments_type(G5_method, Rcall, Gargs, true);

2958   __ call_from_interpreter(Rcall, Gargs, Rret);
2959 }
2960 
2961 void TemplateTable::invokevirtual(int byte_no) {
2962   transition(vtos, vtos);
2963   assert(byte_no == f2_byte, "use this argument");
2964 
2965   Register Rscratch = G3_scratch;
2966   Register Rtemp    = G4_scratch;
2967   Register Rret     = Lscratch;
2968   Register O0_recv  = O0;
2969   Label notFinal;
2970 
2971   load_invoke_cp_cache_entry(byte_no, G5_method, noreg, Rret, true, false, false);
2972   __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
2973 
2974   // Check for vfinal
2975   __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), G4_scratch);
2976   __ btst(Rret, G4_scratch);
2977   __ br(Assembler::zero, false, Assembler::pt, notFinal);


3194   __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch);
3195 
3196   assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below");
3197   __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex);       // Rindex *= 8;
3198   __ add(Rscratch, Rindex, Rscratch);
3199   __ ld_ptr(O2_Klass, Rscratch, G5_method);
3200 
3201   // Check for abstract method error.
3202   {
3203     Label ok;
3204     __ br_notnull_short(G5_method, Assembler::pt, ok);
3205     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3206     __ should_not_reach_here();
3207     __ bind(ok);
3208   }
3209 
3210   Register Rcall = Rinterface;
3211   assert_different_registers(Rcall, G5_method, Gargs, Rret);
3212 
3213   __ profile_arguments_type(G5_method, Rcall, Gargs, true);

3214   __ call_from_interpreter(Rcall, Gargs, Rret);
3215 }
3216 
3217 void TemplateTable::invokehandle(int byte_no) {
3218   transition(vtos, vtos);
3219   assert(byte_no == f1_byte, "use this argument");
3220 
3221   const Register Rret       = Lscratch;
3222   const Register G4_mtype   = G4_scratch;
3223   const Register O0_recv    = O0;
3224   const Register Rscratch   = G3_scratch;
3225 
3226   prepare_invoke(byte_no, G5_method, Rret, G4_mtype, O0_recv);
3227   __ null_check(O0_recv);
3228 
3229   // G4: MethodType object (from cpool->resolved_references[f1], if necessary)
3230   // G5: MH.invokeExact_MT method (from f2)
3231 
3232   // Note:  G4_mtype is already pushed (if necessary) by prepare_invoke
3233 


3469 
3470 void TemplateTable::arraylength() {
3471   transition(atos, itos);
3472   Label ok;
3473   __ verify_oop(Otos_i);
3474   __ tst(Otos_i);
3475   __ throw_if_not_1_x( Assembler::notZero, ok );
3476   __ delayed()->ld(Otos_i, arrayOopDesc::length_offset_in_bytes(), Otos_i);
3477   __ throw_if_not_2( Interpreter::_throw_NullPointerException_entry, G3_scratch, ok);
3478 }
3479 
3480 
3481 void TemplateTable::checkcast() {
3482   transition(atos, atos);
3483   Label done, is_null, quicked, cast_ok, resolved;
3484   Register Roffset = G1_scratch;
3485   Register RobjKlass = O5;
3486   Register RspecifiedKlass = O4;
3487 
3488   // Check for casting a NULL
3489   __ br_null_short(Otos_i, Assembler::pn, is_null);

3490 
3491   // Get value klass in RobjKlass
3492   __ load_klass(Otos_i, RobjKlass); // get value klass
3493 
3494   // Get constant pool tag
3495   __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned);
3496 
3497   // See if the checkcast has been quickened
3498   __ get_cpool_and_tags(Lscratch, G3_scratch);
3499   __ add(G3_scratch, Array<u1>::base_offset_in_bytes(), G3_scratch);
3500   __ ldub(G3_scratch, Roffset, G3_scratch);
3501   __ cmp(G3_scratch, JVM_CONSTANT_Class);
3502   __ br(Assembler::equal, true, Assembler::pt, quicked);
3503   __ delayed()->sll(Roffset, LogBytesPerWord, Roffset);
3504 
3505   __ push_ptr(); // save receiver for result, and for GC
3506   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) );
3507   __ get_vm_result_2(RspecifiedKlass);
3508   __ pop_ptr(Otos_i, G3_scratch); // restore receiver
3509 


3525 
3526   __ bind(cast_ok);
3527 
3528   if (ProfileInterpreter) {
3529     __ ba_short(done);
3530   }
3531   __ bind(is_null);
3532   __ profile_null_seen(G3_scratch);
3533   __ bind(done);
3534 }
3535 
3536 
3537 void TemplateTable::instanceof() {
3538   Label done, is_null, quicked, resolved;
3539   transition(atos, itos);
3540   Register Roffset = G1_scratch;
3541   Register RobjKlass = O5;
3542   Register RspecifiedKlass = O4;
3543 
3544   // Check for casting a NULL
3545   __ br_null_short(Otos_i, Assembler::pt, is_null);

3546 
3547   // Get value klass in RobjKlass
3548   __ load_klass(Otos_i, RobjKlass); // get value klass
3549 
3550   // Get constant pool tag
3551   __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned);
3552 
3553   // See if the checkcast has been quickened
3554   __ get_cpool_and_tags(Lscratch, G3_scratch);
3555   __ add(G3_scratch, Array<u1>::base_offset_in_bytes(), G3_scratch);
3556   __ ldub(G3_scratch, Roffset, G3_scratch);
3557   __ cmp(G3_scratch, JVM_CONSTANT_Class);
3558   __ br(Assembler::equal, true, Assembler::pt, quicked);
3559   __ delayed()->sll(Roffset, LogBytesPerWord, Roffset);
3560 
3561   __ push_ptr(); // save receiver for result, and for GC
3562   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) );
3563   __ get_vm_result_2(RspecifiedKlass);
3564   __ pop_ptr(Otos_i, G3_scratch); // restore receiver
3565 




2932     __ load_receiver(temp, recv);  //  __ argument_address uses Gargs but we need Lesp
2933     __ verify_oop(recv);
2934   }
2935 
2936   // compute return type
2937   __ srl(flags, ConstantPoolCacheEntry::tos_state_shift, ra);
2938   // Make sure we don't need to mask flags after the above shift
2939   ConstantPoolCacheEntry::verify_tos_state_shift();
2940   // load return address
2941   {
2942     const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
2943     AddressLiteral table(table_addr);
2944     __ set(table, temp);
2945     __ sll(ra, LogBytesPerWord, ra);
2946     __ ld_ptr(Address(temp, ra), ra);
2947   }
2948 }
2949 
2950 
2951 void TemplateTable::generate_vtable_call(Register Rrecv, Register Rindex, Register Rret) {
2952   Register Rtemp = G4_scratch;
2953   Register Rcall = Rindex;
2954   assert_different_registers(Rcall, G5_method, Gargs, Rret);
2955 
2956   // get target Method* & entry point
2957   __ lookup_virtual_method(Rrecv, Rindex, G5_method);
2958   __ profile_arguments_type(G5_method, Rcall, Gargs, true);
2959   __ profile_called_method(G5_method, Rtemp);
2960   __ call_from_interpreter(Rcall, Gargs, Rret);
2961 }
2962 
2963 void TemplateTable::invokevirtual(int byte_no) {
2964   transition(vtos, vtos);
2965   assert(byte_no == f2_byte, "use this argument");
2966 
2967   Register Rscratch = G3_scratch;
2968   Register Rtemp    = G4_scratch;
2969   Register Rret     = Lscratch;
2970   Register O0_recv  = O0;
2971   Label notFinal;
2972 
2973   load_invoke_cp_cache_entry(byte_no, G5_method, noreg, Rret, true, false, false);
2974   __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
2975 
2976   // Check for vfinal
2977   __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), G4_scratch);
2978   __ btst(Rret, G4_scratch);
2979   __ br(Assembler::zero, false, Assembler::pt, notFinal);


3196   __ ld(Rscratch, itableOffsetEntry::offset_offset_in_bytes(), Rscratch);
3197 
3198   assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below");
3199   __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex);       // Rindex *= 8;
3200   __ add(Rscratch, Rindex, Rscratch);
3201   __ ld_ptr(O2_Klass, Rscratch, G5_method);
3202 
3203   // Check for abstract method error.
3204   {
3205     Label ok;
3206     __ br_notnull_short(G5_method, Assembler::pt, ok);
3207     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3208     __ should_not_reach_here();
3209     __ bind(ok);
3210   }
3211 
3212   Register Rcall = Rinterface;
3213   assert_different_registers(Rcall, G5_method, Gargs, Rret);
3214 
3215   __ profile_arguments_type(G5_method, Rcall, Gargs, true);
3216   __ profile_called_method(G5_method, Rscratch);
3217   __ call_from_interpreter(Rcall, Gargs, Rret);
3218 }
3219 
3220 void TemplateTable::invokehandle(int byte_no) {
3221   transition(vtos, vtos);
3222   assert(byte_no == f1_byte, "use this argument");
3223 
3224   const Register Rret       = Lscratch;
3225   const Register G4_mtype   = G4_scratch;
3226   const Register O0_recv    = O0;
3227   const Register Rscratch   = G3_scratch;
3228 
3229   prepare_invoke(byte_no, G5_method, Rret, G4_mtype, O0_recv);
3230   __ null_check(O0_recv);
3231 
3232   // G4: MethodType object (from cpool->resolved_references[f1], if necessary)
3233   // G5: MH.invokeExact_MT method (from f2)
3234 
3235   // Note:  G4_mtype is already pushed (if necessary) by prepare_invoke
3236 


3472 
3473 void TemplateTable::arraylength() {
3474   transition(atos, itos);
3475   Label ok;
3476   __ verify_oop(Otos_i);
3477   __ tst(Otos_i);
3478   __ throw_if_not_1_x( Assembler::notZero, ok );
3479   __ delayed()->ld(Otos_i, arrayOopDesc::length_offset_in_bytes(), Otos_i);
3480   __ throw_if_not_2( Interpreter::_throw_NullPointerException_entry, G3_scratch, ok);
3481 }
3482 
3483 
3484 void TemplateTable::checkcast() {
3485   transition(atos, atos);
3486   Label done, is_null, quicked, cast_ok, resolved;
3487   Register Roffset = G1_scratch;
3488   Register RobjKlass = O5;
3489   Register RspecifiedKlass = O4;
3490 
3491   // Check for casting a NULL
3492   __ br_null(Otos_i, false, Assembler::pn, is_null);
3493   __ delayed()->nop();
3494 
3495   // Get value klass in RobjKlass
3496   __ load_klass(Otos_i, RobjKlass); // get value klass
3497 
3498   // Get constant pool tag
3499   __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned);
3500 
3501   // See if the checkcast has been quickened
3502   __ get_cpool_and_tags(Lscratch, G3_scratch);
3503   __ add(G3_scratch, Array<u1>::base_offset_in_bytes(), G3_scratch);
3504   __ ldub(G3_scratch, Roffset, G3_scratch);
3505   __ cmp(G3_scratch, JVM_CONSTANT_Class);
3506   __ br(Assembler::equal, true, Assembler::pt, quicked);
3507   __ delayed()->sll(Roffset, LogBytesPerWord, Roffset);
3508 
3509   __ push_ptr(); // save receiver for result, and for GC
3510   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) );
3511   __ get_vm_result_2(RspecifiedKlass);
3512   __ pop_ptr(Otos_i, G3_scratch); // restore receiver
3513 


3529 
3530   __ bind(cast_ok);
3531 
3532   if (ProfileInterpreter) {
3533     __ ba_short(done);
3534   }
3535   __ bind(is_null);
3536   __ profile_null_seen(G3_scratch);
3537   __ bind(done);
3538 }
3539 
3540 
3541 void TemplateTable::instanceof() {
3542   Label done, is_null, quicked, resolved;
3543   transition(atos, itos);
3544   Register Roffset = G1_scratch;
3545   Register RobjKlass = O5;
3546   Register RspecifiedKlass = O4;
3547 
3548   // Check for casting a NULL
3549   __ br_null(Otos_i, false, Assembler::pt, is_null);
3550   __ delayed()->nop();
3551 
3552   // Get value klass in RobjKlass
3553   __ load_klass(Otos_i, RobjKlass); // get value klass
3554 
3555   // Get constant pool tag
3556   __ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned);
3557 
3558   // See if the checkcast has been quickened
3559   __ get_cpool_and_tags(Lscratch, G3_scratch);
3560   __ add(G3_scratch, Array<u1>::base_offset_in_bytes(), G3_scratch);
3561   __ ldub(G3_scratch, Roffset, G3_scratch);
3562   __ cmp(G3_scratch, JVM_CONSTANT_Class);
3563   __ br(Assembler::equal, true, Assembler::pt, quicked);
3564   __ delayed()->sll(Roffset, LogBytesPerWord, Roffset);
3565 
3566   __ push_ptr(); // save receiver for result, and for GC
3567   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) );
3568   __ get_vm_result_2(RspecifiedKlass);
3569   __ pop_ptr(Otos_i, G3_scratch); // restore receiver
3570 


< prev index next >