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 //