Mercurial > hg > graal-compiler
comparison src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 14260:8cdf3f43f63e
8026253: New type profiling points: sparc support
Summary: c1 and interpreter support for new type profiling on sparc
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 14 Jan 2014 14:51:47 +0100 |
parents | 252d541466ea |
children | d8041d695d19 0bf37f737702 |
comparison
equal
deleted
inserted
replaced
14259:ee5727365ce5 | 14260:8cdf3f43f63e |
---|---|
1313 ShouldNotReachHere(); | 1313 ShouldNotReachHere(); |
1314 } | 1314 } |
1315 } | 1315 } |
1316 | 1316 |
1317 Address LIR_Assembler::as_Address(LIR_Address* addr) { | 1317 Address LIR_Assembler::as_Address(LIR_Address* addr) { |
1318 Register reg = addr->base()->as_register(); | 1318 Register reg = addr->base()->as_pointer_register(); |
1319 LIR_Opr index = addr->index(); | 1319 LIR_Opr index = addr->index(); |
1320 if (index->is_illegal()) { | 1320 if (index->is_illegal()) { |
1321 return Address(reg, addr->disp()); | 1321 return Address(reg, addr->disp()); |
1322 } else { | 1322 } else { |
1323 assert (addr->disp() == 0, "unsupported address mode"); | 1323 assert (addr->disp() == 0, "unsupported address mode"); |
3099 __ st_ptr(tmp1, counter_addr); | 3099 __ st_ptr(tmp1, counter_addr); |
3100 } | 3100 } |
3101 } | 3101 } |
3102 | 3102 |
3103 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { | 3103 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) { |
3104 fatal("Type profiling not implemented on this platform"); | 3104 Register obj = op->obj()->as_register(); |
3105 Register tmp1 = op->tmp()->as_pointer_register(); | |
3106 Register tmp2 = G1; | |
3107 Address mdo_addr = as_Address(op->mdp()->as_address_ptr()); | |
3108 ciKlass* exact_klass = op->exact_klass(); | |
3109 intptr_t current_klass = op->current_klass(); | |
3110 bool not_null = op->not_null(); | |
3111 bool no_conflict = op->no_conflict(); | |
3112 | |
3113 Label update, next, none; | |
3114 | |
3115 bool do_null = !not_null; | |
3116 bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass; | |
3117 bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set; | |
3118 | |
3119 assert(do_null || do_update, "why are we here?"); | |
3120 assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?"); | |
3121 | |
3122 __ verify_oop(obj); | |
3123 | |
3124 if (tmp1 != obj) { | |
3125 __ mov(obj, tmp1); | |
3126 } | |
3127 if (do_null) { | |
3128 __ br_notnull_short(tmp1, Assembler::pt, update); | |
3129 if (!TypeEntries::was_null_seen(current_klass)) { | |
3130 __ ld_ptr(mdo_addr, tmp1); | |
3131 __ or3(tmp1, TypeEntries::null_seen, tmp1); | |
3132 __ st_ptr(tmp1, mdo_addr); | |
3133 } | |
3134 if (do_update) { | |
3135 __ ba(next); | |
3136 __ delayed()->nop(); | |
3137 } | |
3138 #ifdef ASSERT | |
3139 } else { | |
3140 __ br_notnull_short(tmp1, Assembler::pt, update); | |
3141 __ stop("unexpect null obj"); | |
3142 #endif | |
3143 } | |
3144 | |
3145 __ bind(update); | |
3146 | |
3147 if (do_update) { | |
3148 #ifdef ASSERT | |
3149 if (exact_klass != NULL) { | |
3150 Label ok; | |
3151 __ load_klass(tmp1, tmp1); | |
3152 metadata2reg(exact_klass->constant_encoding(), tmp2); | |
3153 __ cmp_and_br_short(tmp1, tmp2, Assembler::equal, Assembler::pt, ok); | |
3154 __ stop("exact klass and actual klass differ"); | |
3155 __ bind(ok); | |
3156 } | |
3157 #endif | |
3158 | |
3159 Label do_update; | |
3160 __ ld_ptr(mdo_addr, tmp2); | |
3161 | |
3162 if (!no_conflict) { | |
3163 if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) { | |
3164 if (exact_klass != NULL) { | |
3165 metadata2reg(exact_klass->constant_encoding(), tmp1); | |
3166 } else { | |
3167 __ load_klass(tmp1, tmp1); | |
3168 } | |
3169 | |
3170 __ xor3(tmp1, tmp2, tmp1); | |
3171 __ btst(TypeEntries::type_klass_mask, tmp1); | |
3172 // klass seen before, nothing to do. The unknown bit may have been | |
3173 // set already but no need to check. | |
3174 __ brx(Assembler::zero, false, Assembler::pt, next); | |
3175 __ delayed()-> | |
3176 | |
3177 btst(TypeEntries::type_unknown, tmp1); | |
3178 // already unknown. Nothing to do anymore. | |
3179 __ brx(Assembler::notZero, false, Assembler::pt, next); | |
3180 | |
3181 if (TypeEntries::is_type_none(current_klass)) { | |
3182 __ delayed()->btst(TypeEntries::type_mask, tmp2); | |
3183 __ brx(Assembler::zero, true, Assembler::pt, do_update); | |
3184 // first time here. Set profile type. | |
3185 __ delayed()->or3(tmp2, tmp1, tmp2); | |
3186 } else { | |
3187 __ delayed()->nop(); | |
3188 } | |
3189 } else { | |
3190 assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && | |
3191 ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only"); | |
3192 | |
3193 __ btst(TypeEntries::type_unknown, tmp2); | |
3194 // already unknown. Nothing to do anymore. | |
3195 __ brx(Assembler::notZero, false, Assembler::pt, next); | |
3196 __ delayed()->nop(); | |
3197 } | |
3198 | |
3199 // different than before. Cannot keep accurate profile. | |
3200 __ or3(tmp2, TypeEntries::type_unknown, tmp2); | |
3201 } else { | |
3202 // There's a single possible klass at this profile point | |
3203 assert(exact_klass != NULL, "should be"); | |
3204 if (TypeEntries::is_type_none(current_klass)) { | |
3205 metadata2reg(exact_klass->constant_encoding(), tmp1); | |
3206 __ xor3(tmp1, tmp2, tmp1); | |
3207 __ btst(TypeEntries::type_klass_mask, tmp1); | |
3208 __ brx(Assembler::zero, false, Assembler::pt, next); | |
3209 #ifdef ASSERT | |
3210 | |
3211 { | |
3212 Label ok; | |
3213 __ delayed()->btst(TypeEntries::type_mask, tmp2); | |
3214 __ brx(Assembler::zero, true, Assembler::pt, ok); | |
3215 __ delayed()->nop(); | |
3216 | |
3217 __ stop("unexpected profiling mismatch"); | |
3218 __ bind(ok); | |
3219 } | |
3220 // first time here. Set profile type. | |
3221 __ or3(tmp2, tmp1, tmp2); | |
3222 #else | |
3223 // first time here. Set profile type. | |
3224 __ delayed()->or3(tmp2, tmp1, tmp2); | |
3225 #endif | |
3226 | |
3227 } else { | |
3228 assert(ciTypeEntries::valid_ciklass(current_klass) != NULL && | |
3229 ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent"); | |
3230 | |
3231 // already unknown. Nothing to do anymore. | |
3232 __ btst(TypeEntries::type_unknown, tmp2); | |
3233 __ brx(Assembler::notZero, false, Assembler::pt, next); | |
3234 __ delayed()->or3(tmp2, TypeEntries::type_unknown, tmp2); | |
3235 } | |
3236 } | |
3237 | |
3238 __ bind(do_update); | |
3239 __ st_ptr(tmp2, mdo_addr); | |
3240 | |
3241 __ bind(next); | |
3242 } | |
3105 } | 3243 } |
3106 | 3244 |
3107 void LIR_Assembler::align_backward_branch_target() { | 3245 void LIR_Assembler::align_backward_branch_target() { |
3108 __ align(OptoLoopAlignment); | 3246 __ align(OptoLoopAlignment); |
3109 } | 3247 } |
3319 } | 3457 } |
3320 | 3458 |
3321 | 3459 |
3322 void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { | 3460 void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) { |
3323 LIR_Address* addr = addr_opr->as_address_ptr(); | 3461 LIR_Address* addr = addr_opr->as_address_ptr(); |
3324 assert(addr->index()->is_illegal() && addr->scale() == LIR_Address::times_1 && Assembler::is_simm13(addr->disp()), "can't handle complex addresses yet"); | 3462 assert(addr->index()->is_illegal() && addr->scale() == LIR_Address::times_1, "can't handle complex addresses yet"); |
3325 | 3463 |
3326 __ add(addr->base()->as_pointer_register(), addr->disp(), dest->as_pointer_register()); | 3464 if (Assembler::is_simm13(addr->disp())) { |
3465 __ add(addr->base()->as_pointer_register(), addr->disp(), dest->as_pointer_register()); | |
3466 } else { | |
3467 __ set(addr->disp(), G3_scratch); | |
3468 __ add(addr->base()->as_pointer_register(), G3_scratch, dest->as_pointer_register()); | |
3469 } | |
3327 } | 3470 } |
3328 | 3471 |
3329 | 3472 |
3330 void LIR_Assembler::get_thread(LIR_Opr result_reg) { | 3473 void LIR_Assembler::get_thread(LIR_Opr result_reg) { |
3331 assert(result_reg->is_register(), "check"); | 3474 assert(result_reg->is_register(), "check"); |