Fri, 13 Jul 2018 14:14:12 +0800
#7277 Implement LIR_Assembler::emit_profile_type for MIPS
Reviewed-by: fujie, aoqi
src/cpu/mips/vm/c1_LIRAssembler_mips.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/c1/c1_LIR.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Thu Jul 12 15:30:06 2018 +0800 1.2 +++ b/src/cpu/mips/vm/c1_LIRAssembler_mips.cpp Fri Jul 13 14:14:12 2018 +0800 1.3 @@ -1,6 +1,6 @@ 1.4 /* 1.5 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 - * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved. 1.7 + * Copyright (c) 2015, 2018, Loongson Technology. All rights reserved. 1.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.9 * 1.10 * This code is free software; you can redistribute it and/or modify it 1.11 @@ -5746,8 +5746,344 @@ 1.12 } 1.13 1.14 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { 1.15 - // Newly added in OpenJDK 8 1.16 - Unimplemented(); 1.17 + Register obj = op->obj()->as_register(); 1.18 + Register tmp = op->tmp()->as_pointer_register(); 1.19 + Register tmp1 = T1; 1.20 + Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); 1.21 + ciKlass* exact_klass = op->exact_klass(); 1.22 + intptr_t current_klass = op->current_klass(); 1.23 + bool not_null = op->not_null(); 1.24 + bool no_conflict = op->no_conflict(); 1.25 + 1.26 + Label update, next, none; 1.27 + 1.28 + bool do_null = !not_null; 1.29 + bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; 1.30 + bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; 1.31 + 1.32 + assert(do_null || do_update, "why are we here?"); 1.33 + assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); 1.34 + 1.35 + __ verify_oop(obj); 1.36 + 1.37 + if (tmp != obj) { 1.38 + __ move(tmp, obj); 1.39 + } 1.40 + if (do_null) { 1.41 + __ bne(tmp, R0, update); 1.42 + __ delayed()->nop(); 1.43 + if (!TypeEntries::was_null_seen(current_klass)) { 1.44 + __ push(tmp1); 1.45 + if (mdo_addr.index() == noreg) { 1.46 + __ ld(tmp1, mdo_addr); 1.47 + } else { 1.48 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.49 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.50 + 1.51 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.52 + __ daddu(AT, AT, mdo_addr.base()); 1.53 + __ ld(tmp1, AT, mdo_addr.disp()); 1.54 + } 1.55 + __ li(AT, TypeEntries::null_seen); 1.56 + __ orr(AT, tmp1, AT); 1.57 + if (mdo_addr.index() == noreg) { 1.58 + __ sd(AT, mdo_addr); 1.59 + } else { 1.60 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.61 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.62 + 1.63 + __ dsll(tmp1, mdo_addr.index(), mdo_addr.scale()); 1.64 + __ daddu(tmp1, tmp1, mdo_addr.base()); 1.65 + __ sd(AT, tmp1, mdo_addr.disp()); 1.66 + } 1.67 + __ pop(tmp1); 1.68 + 1.69 + } 1.70 + if (do_update) { 1.71 +#ifndef ASSERT 1.72 + __ b(next); 1.73 + __ delayed()->nop(); 1.74 + } 1.75 +#else 1.76 + __ b(next); 1.77 + __ delayed()->nop(); 1.78 + } 1.79 + } else { 1.80 + __ bne(tmp, R0, update); 1.81 + __ delayed()->nop(); 1.82 + __ stop("unexpect null obj"); 1.83 +#endif 1.84 + } 1.85 + 1.86 + __ bind(update); 1.87 + 1.88 + if (do_update) { 1.89 +#ifdef ASSERT 1.90 + if (exact_klass != NULL) { 1.91 + Label ok; 1.92 + __ load_klass(tmp, tmp); 1.93 + __ push(tmp); 1.94 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.95 + __ ld(AT, Address(SP, 0)); 1.96 + __ beq(tmp, AT, ok); 1.97 + __ delayed()->nop(); 1.98 + __ stop("exact klass and actual klass differ"); 1.99 + __ bind(ok); 1.100 + __ pop(tmp); 1.101 + } 1.102 +#endif 1.103 + if (!no_conflict) { 1.104 + if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { 1.105 + if (exact_klass != NULL) { 1.106 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.107 + } else { 1.108 + __ load_klass(tmp, tmp); 1.109 + } 1.110 + 1.111 + if (mdo_addr.index() == noreg) { 1.112 + __ ld(AT, mdo_addr); 1.113 + } else { 1.114 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.115 + __ daddu(AT, AT, mdo_addr.base()); 1.116 + __ ld(AT, AT, mdo_addr.disp()); 1.117 + } 1.118 + __ xorr(tmp, tmp, AT); 1.119 + __ li(AT, TypeEntries::type_klass_mask); 1.120 + __ andr(AT, tmp, AT); 1.121 + // klass seen before, nothing to do. The unknown bit may have been 1.122 + // set already but no need to check. 1.123 + __ beq(AT, R0, next); 1.124 + __ delayed()->nop(); 1.125 + 1.126 + __ li(AT, TypeEntries::type_unknown); 1.127 + __ andr(AT, tmp, AT); 1.128 + __ bne(AT, R0, next); // already unknown. Nothing to do anymore. 1.129 + __ delayed()->nop(); 1.130 + 1.131 + if (TypeEntries::is_type_none(current_klass)) { 1.132 + if (mdo_addr.index() == noreg) { 1.133 + __ ld(AT, mdo_addr); 1.134 + } else { 1.135 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.136 + __ daddu(AT, AT, mdo_addr.base()); 1.137 + __ ld(AT, AT, mdo_addr.disp()); 1.138 + } 1.139 + __ beq(AT, R0, none); 1.140 + __ delayed()->nop(); 1.141 + 1.142 + __ push(tmp1); 1.143 + if (mdo_addr.index() == noreg) { 1.144 + __ ld(tmp1, mdo_addr); 1.145 + } else { 1.146 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.147 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.148 + 1.149 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.150 + __ daddu(AT, AT, mdo_addr.base()); 1.151 + __ ld(tmp1, AT, mdo_addr.disp()); 1.152 + } 1.153 + __ li(AT, TypeEntries::null_seen); 1.154 + __ subu(AT, AT, tmp1); 1.155 + __ pop(tmp1); 1.156 + __ beq(AT, R0, none); 1.157 + __ delayed()->nop(); 1.158 + // There is a chance that the checks above (re-reading profiling 1.159 + // data from memory) fail if another thread has just set the 1.160 + // profiling to this obj's klass 1.161 + 1.162 + if (mdo_addr.index() == noreg) { 1.163 + __ ld(AT, mdo_addr); 1.164 + } else { 1.165 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.166 + __ daddu(AT, AT, mdo_addr.base()); 1.167 + __ ld(AT, AT, mdo_addr.disp()); 1.168 + } 1.169 + __ xorr(tmp, tmp, AT); 1.170 + __ li(AT, TypeEntries::type_klass_mask); 1.171 + __ andr(AT, tmp, AT); 1.172 + __ beq(AT, R0, next); 1.173 + __ delayed()->nop(); 1.174 + } 1.175 + } else { 1.176 + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && 1.177 + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); 1.178 + if (mdo_addr.index() == noreg) { 1.179 + __ ld(tmp, mdo_addr); 1.180 + } else { 1.181 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.182 + __ daddu(AT, AT, mdo_addr.base()); 1.183 + __ ld(tmp, AT, mdo_addr.disp()); 1.184 + } 1.185 + __ li(AT, TypeEntries::type_unknown); 1.186 + __ andr(AT, tmp, AT); 1.187 + __ bne(AT, R0, next); // already unknown. Nothing to do anymore. 1.188 + __ delayed()->nop(); 1.189 + } 1.190 + 1.191 + // different than before. Cannot keep accurate profile. 1.192 + __ push(tmp1); 1.193 + if (mdo_addr.index() == noreg) { 1.194 + __ ld(tmp1, mdo_addr); 1.195 + } else { 1.196 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.197 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.198 + 1.199 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.200 + __ daddu(AT, AT, mdo_addr.base()); 1.201 + __ ld(tmp1, AT, mdo_addr.disp()); 1.202 + } 1.203 + __ li(AT, TypeEntries::type_unknown); 1.204 + __ orr(AT, tmp1, AT); 1.205 + if (mdo_addr.index() == noreg) { 1.206 + __ sd(AT, mdo_addr); 1.207 + } else { 1.208 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.209 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.210 + 1.211 + __ dsll(tmp1, mdo_addr.index(), mdo_addr.scale()); 1.212 + __ daddu(tmp1, tmp1, mdo_addr.base()); 1.213 + __ sd(AT, tmp1, mdo_addr.disp()); 1.214 + } 1.215 + __ pop(tmp1); 1.216 + 1.217 + if (TypeEntries::is_type_none(current_klass)) { 1.218 + __ b(next); 1.219 + __ delayed()->nop(); 1.220 + 1.221 + __ bind(none); 1.222 + // first time here. Set profile type. 1.223 + if (mdo_addr.index() == noreg) { 1.224 + __ sd(tmp, mdo_addr); 1.225 + } else { 1.226 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.227 + __ daddu(AT, AT, mdo_addr.base()); 1.228 + __ sd(tmp, AT, mdo_addr.disp()); 1.229 + } 1.230 + } 1.231 + } else { 1.232 + // There's a single possible klass at this profile point 1.233 + assert(exact_klass != NULL, "should be"); 1.234 + if (TypeEntries::is_type_none(current_klass)) { 1.235 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.236 + if (mdo_addr.index() == noreg) { 1.237 + __ ld(AT, mdo_addr); 1.238 + } else { 1.239 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.240 + __ daddu(AT, AT, mdo_addr.base()); 1.241 + __ ld(AT, AT, mdo_addr.disp()); 1.242 + } 1.243 + __ xorr(tmp, tmp, AT); 1.244 + __ li(AT, TypeEntries::type_klass_mask); 1.245 + __ andr(AT, tmp, AT); 1.246 +#ifdef ASSERT 1.247 + __ beq_far(AT, R0, next); 1.248 + __ delayed()->nop(); 1.249 + 1.250 + { 1.251 + Label ok; 1.252 + __ push(tmp); 1.253 + if (mdo_addr.index() == noreg) { 1.254 + __ ld(AT, mdo_addr); 1.255 + } else { 1.256 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.257 + __ daddu(AT, AT, mdo_addr.base()); 1.258 + __ ld(AT, AT, mdo_addr.disp()); 1.259 + } 1.260 + __ beq_far(AT, R0, ok); 1.261 + __ delayed()->nop(); 1.262 + 1.263 + __ push(tmp1); 1.264 + if (mdo_addr.index() == noreg) { 1.265 + __ ld(tmp1, mdo_addr); 1.266 + } else { 1.267 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.268 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.269 + 1.270 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.271 + __ daddu(AT, AT, mdo_addr.base()); 1.272 + __ ld(tmp1, AT, mdo_addr.disp()); 1.273 + } 1.274 + __ li(AT, TypeEntries::null_seen); 1.275 + __ subu(AT, AT, tmp1); 1.276 + __ pop(tmp1); 1.277 + __ beq_far(AT, R0, ok); 1.278 + __ delayed()->nop(); 1.279 + // may have been set by another thread 1.280 + __ mov_metadata(tmp, exact_klass->constant_encoding()); 1.281 + if (mdo_addr.index() == noreg) { 1.282 + __ ld(AT, mdo_addr); 1.283 + } else { 1.284 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.285 + __ daddu(AT, AT, mdo_addr.base()); 1.286 + __ ld(AT, AT, mdo_addr.disp()); 1.287 + } 1.288 + __ xorr(tmp, tmp, AT); 1.289 + __ li(AT, TypeEntries::type_mask); 1.290 + __ andr(AT, tmp, AT); 1.291 + __ beq_far(AT, R0, ok); 1.292 + __ delayed()->nop(); 1.293 + 1.294 + __ stop("unexpected profiling mismatch"); 1.295 + __ bind(ok); 1.296 + __ pop(tmp); 1.297 + } 1.298 +#else 1.299 + __ beq(AT, R0, next); 1.300 + __ delayed()->nop(); 1.301 +#endif 1.302 + // first time here. Set profile type. 1.303 + if (mdo_addr.index() == noreg) { 1.304 + __ sd(tmp, mdo_addr); 1.305 + } else { 1.306 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.307 + __ daddu(AT, AT, mdo_addr.base()); 1.308 + __ sd(tmp, AT, mdo_addr.disp()); 1.309 + } 1.310 + } else { 1.311 + assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && 1.312 + ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); 1.313 + 1.314 + if (mdo_addr.index() == noreg) { 1.315 + __ ld(tmp, mdo_addr); 1.316 + } else { 1.317 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.318 + __ daddu(AT, AT, mdo_addr.base()); 1.319 + __ ld(tmp, AT, mdo_addr.disp()); 1.320 + } 1.321 + __ li(AT, TypeEntries::type_unknown); 1.322 + __ andr(AT, tmp, AT); 1.323 + __ bne(AT, R0, next); // already unknown. Nothing to do anymore. 1.324 + __ delayed()->nop(); 1.325 + 1.326 + __ push(tmp1); 1.327 + if (mdo_addr.index() == noreg) { 1.328 + __ ld(tmp1, mdo_addr); 1.329 + } else { 1.330 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.331 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.332 + 1.333 + __ dsll(AT, mdo_addr.index(), mdo_addr.scale()); 1.334 + __ daddu(AT, AT, mdo_addr.base()); 1.335 + __ ld(tmp1, AT, mdo_addr.disp()); 1.336 + } 1.337 + __ li(AT, TypeEntries::type_unknown); 1.338 + __ orr(AT, tmp1, AT); 1.339 + if (mdo_addr.index() == noreg) { 1.340 + __ sd(AT, mdo_addr); 1.341 + } else { 1.342 + guarantee(tmp1 != mdo_addr.base(), "The base register will be corrupted !"); 1.343 + guarantee(tmp1 != mdo_addr.index(), "The index register will be corrupted !"); 1.344 + 1.345 + __ dsll(tmp1, mdo_addr.index(), mdo_addr.scale()); 1.346 + __ daddu(tmp1, tmp1, mdo_addr.base()); 1.347 + __ sd(AT, tmp1, mdo_addr.disp()); 1.348 + } 1.349 + __ pop(tmp1); 1.350 + } 1.351 + } 1.352 + 1.353 + __ bind(next); 1.354 + } 1.355 } 1.356 1.357 void LIR_Assembler::emit_delay(LIR_OpDelay*) {
2.1 --- a/src/share/vm/c1/c1_LIR.cpp Thu Jul 12 15:30:06 2018 +0800 2.2 +++ b/src/share/vm/c1/c1_LIR.cpp Fri Jul 13 14:14:12 2018 +0800 2.3 @@ -23,8 +23,8 @@ 2.4 */ 2.5 2.6 /* 2.7 - * This file has been modified by Loongson Technology in 2015. These 2.8 - * modifications are Copyright (c) 2015 Loongson Technology, and are made 2.9 + * This file has been modified by Loongson Technology in 2015, 2018. These 2.10 + * modifications are Copyright (c) 2015, 2018 Loongson Technology, and are made 2.11 * available on the same license terms set forth above. 2.12 */ 2.13 2.14 @@ -2348,7 +2348,12 @@ 2.15 2.16 // LIR_OpProfileType 2.17 void LIR_OpProfileType::print_instr(outputStream* out) const { 2.18 - out->print("exact = "); exact_klass()->print_name_on(out); 2.19 + out->print("exact = "); 2.20 + if (exact_klass() == NULL) { 2.21 + out->print("unknown"); 2.22 + } else { 2.23 + exact_klass()->print_name_on(out); 2.24 + } 2.25 out->print("current = "); ciTypeEntries::print_ciklass(out, current_klass()); 2.26 mdp()->print(out); out->print(" "); 2.27 obj()->print(out); out->print(" ");