1.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Oct 09 11:05:17 2013 -0700 1.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Oct 09 16:32:21 2013 +0200 1.3 @@ -3632,6 +3632,161 @@ 1.4 } 1.5 } 1.6 1.7 +void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { 1.8 + Register obj = op->obj()->as_register(); 1.9 + Register tmp = op->tmp()->as_pointer_register(); 1.10 + Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); 1.11 + ciKlass* exact_klass = op->exact_klass(); 1.12 + intptr_t current_klass = op->current_klass(); 1.13 + bool not_null = op->not_null(); 1.14 + bool no_conflict = op->no_conflict(); 1.15 + 1.16 + Label update, next, none; 1.17 + 1.18 + bool do_null = !not_null; 1.19 + bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; 1.20 + bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; 1.21 + 1.22 + assert(do_null || do_update, "why are we here?"); 1.23 + assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); 1.24 + 1.25 + __ verify_oop(obj); 1.26 + 1.27 + if (tmp != obj) { 1.28 + __ mov(tmp, obj); 1.29 + } 1.30 + if (do_null) { 1.31 + __ testptr(tmp, tmp); 1.32 + __ jccb(Assembler::notZero, update); 1.33 + if (!TypeEntries::was_null_seen(current_klass)) { 1.34 + __ orptr(mdo_addr, TypeEntries::null_seen); 1.35 + } 1.36 + if (do_update) { 1.37 +#ifndef ASSERT 1.38 + __ jmpb(next); 1.39 + } 1.40 +#else 1.41 + __ jmp(next); 1.42 + } 1.43 + } else { 1.44 + __ testptr(tmp, tmp); 1.45 + __ jccb(Assembler::notZero, update); 1.46 + __ stop("unexpect null obj"); 1.47 +#endif 1.48 + } 1.49 + 1.50 + __ bind(update); 1.51 + 1.52 + if (do_update) { 1.53 +#ifdef ASSERT 1.54 + if (exact_klass != NULL) { 1.55 + Label ok; 1.56 + __ load_klass(tmp, tmp); 1.57 + __ push(tmp); 1.58 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.59 + __ cmpptr(tmp, Address(rsp, 0)); 1.60 + __ jccb(Assembler::equal, ok); 1.61 + __ stop("exact klass and actual klass differ"); 1.62 + __ bind(ok); 1.63 + __ pop(tmp); 1.64 + } 1.65 +#endif 1.66 + if (!no_conflict) { 1.67 + if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { 1.68 + if (exact_klass != NULL) { 1.69 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.70 + } else { 1.71 + __ load_klass(tmp, tmp); 1.72 + } 1.73 + 1.74 + __ xorptr(tmp, mdo_addr); 1.75 + __ testptr(tmp, TypeEntries::type_klass_mask); 1.76 + // klass seen before, nothing to do. The unknown bit may have been 1.77 + // set already but no need to check. 1.78 + __ jccb(Assembler::zero, next); 1.79 + 1.80 + __ testptr(tmp, TypeEntries::type_unknown); 1.81 + __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. 1.82 + 1.83 + if (TypeEntries::is_type_none(current_klass)) { 1.84 + __ cmpptr(mdo_addr, 0); 1.85 + __ jccb(Assembler::equal, none); 1.86 + __ cmpptr(mdo_addr, TypeEntries::null_seen); 1.87 + __ jccb(Assembler::equal, none); 1.88 + // There is a chance that the checks above (re-reading profiling 1.89 + // data from memory) fail if another thread has just set the 1.90 + // profiling to this obj's klass 1.91 + __ xorptr(tmp, mdo_addr); 1.92 + __ testptr(tmp, TypeEntries::type_klass_mask); 1.93 + __ jccb(Assembler::zero, next); 1.94 + } 1.95 + } else { 1.96 + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && 1.97 + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); 1.98 + 1.99 + __ movptr(tmp, mdo_addr); 1.100 + __ testptr(tmp, TypeEntries::type_unknown); 1.101 + __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. 1.102 + } 1.103 + 1.104 + // different than before. Cannot keep accurate profile. 1.105 + __ orptr(mdo_addr, TypeEntries::type_unknown); 1.106 + 1.107 + if (TypeEntries::is_type_none(current_klass)) { 1.108 + __ jmpb(next); 1.109 + 1.110 + __ bind(none); 1.111 + // first time here. Set profile type. 1.112 + __ movptr(mdo_addr, tmp); 1.113 + } 1.114 + } else { 1.115 + // There's a single possible klass at this profile point 1.116 + assert(exact_klass != NULL, "should be"); 1.117 + if (TypeEntries::is_type_none(current_klass)) { 1.118 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.119 + __ xorptr(tmp, mdo_addr); 1.120 + __ testptr(tmp, TypeEntries::type_klass_mask); 1.121 +#ifdef ASSERT 1.122 + __ jcc(Assembler::zero, next); 1.123 + 1.124 + { 1.125 + Label ok; 1.126 + __ push(tmp); 1.127 + __ cmpptr(mdo_addr, 0); 1.128 + __ jcc(Assembler::equal, ok); 1.129 + __ cmpptr(mdo_addr, TypeEntries::null_seen); 1.130 + __ jcc(Assembler::equal, ok); 1.131 + // may have been set by another thread 1.132 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.133 + __ xorptr(tmp, mdo_addr); 1.134 + __ testptr(tmp, TypeEntries::type_mask); 1.135 + __ jcc(Assembler::zero, ok); 1.136 + 1.137 + __ stop("unexpected profiling mismatch"); 1.138 + __ bind(ok); 1.139 + __ pop(tmp); 1.140 + } 1.141 +#else 1.142 + __ jccb(Assembler::zero, next); 1.143 +#endif 1.144 + // first time here. Set profile type. 1.145 + __ movptr(mdo_addr, tmp); 1.146 + } else { 1.147 + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && 1.148 + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); 1.149 + 1.150 + __ movptr(tmp, mdo_addr); 1.151 + __ testptr(tmp, TypeEntries::type_unknown); 1.152 + __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore. 1.153 + 1.154 + __ orptr(mdo_addr, TypeEntries::type_unknown); 1.155 + } 1.156 + } 1.157 + 1.158 + __ bind(next); 1.159 + } 1.160 +} 1.161 + 1.162 void LIR_Assembler::emit_delay(LIR_OpDelay*) { 1.163 Unimplemented(); 1.164 }