src/cpu/x86/vm/stubGenerator_x86_32.cpp

changeset 1082
bd441136a5ce
parent 1014
0fbdb4381b99
parent 1079
c517646eef23
child 1145
e5b0439ef4ae
     1.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Mar 18 11:37:48 2009 -0400
     1.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Mar 19 09:13:24 2009 -0700
     1.3 @@ -1310,81 +1310,51 @@
     1.4                             Address& super_check_offset_addr,
     1.5                             Address& super_klass_addr,
     1.6                             Register temp,
     1.7 -                           Label* L_success_ptr, Label* L_failure_ptr) {
     1.8 +                           Label* L_success, Label* L_failure) {
     1.9      BLOCK_COMMENT("type_check:");
    1.10  
    1.11      Label L_fallthrough;
    1.12 -    bool fall_through_on_success = (L_success_ptr == NULL);
    1.13 -    if (fall_through_on_success) {
    1.14 -      L_success_ptr = &L_fallthrough;
    1.15 -    } else {
    1.16 -      L_failure_ptr = &L_fallthrough;
    1.17 -    }
    1.18 -    Label& L_success = *L_success_ptr;
    1.19 -    Label& L_failure = *L_failure_ptr;
    1.20 +#define LOCAL_JCC(assembler_con, label_ptr)                             \
    1.21 +    if (label_ptr != NULL)  __ jcc(assembler_con, *(label_ptr));        \
    1.22 +    else                    __ jcc(assembler_con, L_fallthrough) /*omit semi*/
    1.23  
    1.24 +    // The following is a strange variation of the fast path which requires
    1.25 +    // one less register, because needed values are on the argument stack.
    1.26 +    // __ check_klass_subtype_fast_path(sub_klass, *super_klass*, temp,
    1.27 +    //                                  L_success, L_failure, NULL);
    1.28      assert_different_registers(sub_klass, temp);
    1.29  
    1.30 -    // a couple of useful fields in sub_klass:
    1.31 -    int ss_offset = (klassOopDesc::header_size() * HeapWordSize +
    1.32 -                     Klass::secondary_supers_offset_in_bytes());
    1.33      int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
    1.34                       Klass::secondary_super_cache_offset_in_bytes());
    1.35 -    Address secondary_supers_addr(sub_klass, ss_offset);
    1.36 -    Address super_cache_addr(     sub_klass, sc_offset);
    1.37  
    1.38      // if the pointers are equal, we are done (e.g., String[] elements)
    1.39      __ cmpptr(sub_klass, super_klass_addr);
    1.40 -    __ jcc(Assembler::equal, L_success);
    1.41 +    LOCAL_JCC(Assembler::equal, L_success);
    1.42  
    1.43      // check the supertype display:
    1.44      __ movl2ptr(temp, super_check_offset_addr);
    1.45      Address super_check_addr(sub_klass, temp, Address::times_1, 0);
    1.46      __ movptr(temp, super_check_addr); // load displayed supertype
    1.47      __ cmpptr(temp, super_klass_addr); // test the super type
    1.48 -    __ jcc(Assembler::equal, L_success);
    1.49 +    LOCAL_JCC(Assembler::equal, L_success);
    1.50  
    1.51      // if it was a primary super, we can just fail immediately
    1.52      __ cmpl(super_check_offset_addr, sc_offset);
    1.53 -    __ jcc(Assembler::notEqual, L_failure);
    1.54 +    LOCAL_JCC(Assembler::notEqual, L_failure);
    1.55  
    1.56 -    // Now do a linear scan of the secondary super-klass chain.
    1.57 -    // This code is rarely used, so simplicity is a virtue here.
    1.58 -    inc_counter_np(SharedRuntime::_partial_subtype_ctr);
    1.59 -    {
    1.60 -      // The repne_scan instruction uses fixed registers, which we must spill.
    1.61 -      // (We need a couple more temps in any case.)
    1.62 -      __ push(rax);
    1.63 -      __ push(rcx);
    1.64 -      __ push(rdi);
    1.65 -      assert_different_registers(sub_klass, rax, rcx, rdi);
    1.66 +    // The repne_scan instruction uses fixed registers, which will get spilled.
    1.67 +    // We happen to know this works best when super_klass is in rax.
    1.68 +    Register super_klass = temp;
    1.69 +    __ movptr(super_klass, super_klass_addr);
    1.70 +    __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg,
    1.71 +                                     L_success, L_failure);
    1.72  
    1.73 -      __ movptr(rdi, secondary_supers_addr);
    1.74 -      // Load the array length.
    1.75 -      __ movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
    1.76 -      // Skip to start of data.
    1.77 -      __ addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
    1.78 -      // Scan rcx words at [edi] for occurance of rax,
    1.79 -      // Set NZ/Z based on last compare
    1.80 -      __ movptr(rax, super_klass_addr);
    1.81 -      __ repne_scan();
    1.82 +    __ bind(L_fallthrough);
    1.83  
    1.84 -      // Unspill the temp. registers:
    1.85 -      __ pop(rdi);
    1.86 -      __ pop(rcx);
    1.87 -      __ pop(rax);
    1.88 -    }
    1.89 -    __ jcc(Assembler::notEqual, L_failure);
    1.90 +    if (L_success == NULL) { BLOCK_COMMENT("L_success:"); }
    1.91 +    if (L_failure == NULL) { BLOCK_COMMENT("L_failure:"); }
    1.92  
    1.93 -    // Success.  Cache the super we found and proceed in triumph.
    1.94 -    __ movptr(temp, super_klass_addr); // note: rax, is dead
    1.95 -    __ movptr(super_cache_addr, temp);
    1.96 -
    1.97 -    if (!fall_through_on_success)
    1.98 -      __ jmp(L_success);
    1.99 -
   1.100 -    // Fall through on failure!
   1.101 -    __ bind(L_fallthrough);
   1.102 +#undef LOCAL_JCC
   1.103    }
   1.104  
   1.105    //

mercurial