Mercurial > hg > truffle
comparison src/share/vm/opto/graphKit.cpp @ 362:f8199438385b
Merge
author | apetrusenko |
---|---|
date | Wed, 17 Sep 2008 16:49:18 +0400 |
parents | 1ee8caae33af |
children | 5f44674206d3 |
comparison
equal
deleted
inserted
replaced
316:5fa96a5a7e76 | 362:f8199438385b |
---|---|
1178 else if (type == T_OBJECT) | 1178 else if (type == T_OBJECT) |
1179 reason = Deoptimization::Reason_null_check; | 1179 reason = Deoptimization::Reason_null_check; |
1180 else | 1180 else |
1181 reason = Deoptimization::Reason_div0_check; | 1181 reason = Deoptimization::Reason_div0_check; |
1182 | 1182 |
1183 // %%% Since Reason_unhandled is not recorded on a per-bytecode basis, | |
1184 // ciMethodData::has_trap_at will return a conservative -1 if any | |
1185 // must-be-null assertion has failed. This could cause performance | |
1186 // problems for a method after its first do_null_assert failure. | |
1187 // Consider using 'Reason_class_check' instead? | |
1188 | |
1183 // To cause an implicit null check, we set the not-null probability | 1189 // To cause an implicit null check, we set the not-null probability |
1184 // to the maximum (PROB_MAX). For an explicit check the probablity | 1190 // to the maximum (PROB_MAX). For an explicit check the probablity |
1185 // is set to a smaller value. | 1191 // is set to a smaller value. |
1186 if (null_control != NULL || too_many_traps(reason)) { | 1192 if (null_control != NULL || too_many_traps(reason)) { |
1187 // probability is less likely | 1193 // probability is less likely |
1364 const Type* val_type, | 1370 const Type* val_type, |
1365 BasicType bt) { | 1371 BasicType bt) { |
1366 BarrierSet* bs = Universe::heap()->barrier_set(); | 1372 BarrierSet* bs = Universe::heap()->barrier_set(); |
1367 set_control(ctl); | 1373 set_control(ctl); |
1368 switch (bs->kind()) { | 1374 switch (bs->kind()) { |
1375 case BarrierSet::G1SATBCT: | |
1376 case BarrierSet::G1SATBCTLogging: | |
1377 g1_write_barrier_pre(obj, adr, adr_idx, val, val_type, bt); | |
1378 break; | |
1369 | 1379 |
1370 case BarrierSet::CardTableModRef: | 1380 case BarrierSet::CardTableModRef: |
1371 case BarrierSet::CardTableExtension: | 1381 case BarrierSet::CardTableExtension: |
1372 case BarrierSet::ModRef: | 1382 case BarrierSet::ModRef: |
1373 break; | 1383 break; |
1388 BasicType bt, | 1398 BasicType bt, |
1389 bool use_precise) { | 1399 bool use_precise) { |
1390 BarrierSet* bs = Universe::heap()->barrier_set(); | 1400 BarrierSet* bs = Universe::heap()->barrier_set(); |
1391 set_control(ctl); | 1401 set_control(ctl); |
1392 switch (bs->kind()) { | 1402 switch (bs->kind()) { |
1403 case BarrierSet::G1SATBCT: | |
1404 case BarrierSet::G1SATBCTLogging: | |
1405 g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise); | |
1406 break; | |
1393 | 1407 |
1394 case BarrierSet::CardTableModRef: | 1408 case BarrierSet::CardTableModRef: |
1395 case BarrierSet::CardTableExtension: | 1409 case BarrierSet::CardTableExtension: |
1396 write_barrier_post(store, obj, adr, val, use_precise); | 1410 write_barrier_post(store, obj, adr, val, use_precise); |
1397 break; | 1411 break; |
3173 return init->as_Initialize(); | 3187 return init->as_Initialize(); |
3174 } | 3188 } |
3175 } | 3189 } |
3176 return NULL; | 3190 return NULL; |
3177 } | 3191 } |
3192 | |
3193 void GraphKit::g1_write_barrier_pre(Node* obj, | |
3194 Node* adr, | |
3195 uint alias_idx, | |
3196 Node* val, | |
3197 const Type* val_type, | |
3198 BasicType bt) { | |
3199 IdealKit ideal(gvn(), control(), merged_memory(), true); | |
3200 #define __ ideal. | |
3201 __ declares_done(); | |
3202 | |
3203 Node* thread = __ thread(); | |
3204 | |
3205 Node* no_ctrl = NULL; | |
3206 Node* no_base = __ top(); | |
3207 Node* zero = __ ConI(0); | |
3208 | |
3209 float likely = PROB_LIKELY(0.999); | |
3210 float unlikely = PROB_UNLIKELY(0.999); | |
3211 | |
3212 BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE; | |
3213 assert(in_bytes(PtrQueue::byte_width_of_active()) == 4 || in_bytes(PtrQueue::byte_width_of_active()) == 1, "flag width"); | |
3214 | |
3215 // Offsets into the thread | |
3216 const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 648 | |
3217 PtrQueue::byte_offset_of_active()); | |
3218 const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656 | |
3219 PtrQueue::byte_offset_of_index()); | |
3220 const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652 | |
3221 PtrQueue::byte_offset_of_buf()); | |
3222 // Now the actual pointers into the thread | |
3223 | |
3224 // set_control( ctl); | |
3225 | |
3226 Node* marking_adr = __ AddP(no_base, thread, __ ConX(marking_offset)); | |
3227 Node* buffer_adr = __ AddP(no_base, thread, __ ConX(buffer_offset)); | |
3228 Node* index_adr = __ AddP(no_base, thread, __ ConX(index_offset)); | |
3229 | |
3230 // Now some of the values | |
3231 | |
3232 Node* marking = __ load(no_ctrl, marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); | |
3233 Node* index = __ load(no_ctrl, index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); | |
3234 Node* buffer = __ load(no_ctrl, buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); | |
3235 | |
3236 // if (!marking) | |
3237 __ if_then(marking, BoolTest::ne, zero); { | |
3238 | |
3239 const Type* t1 = adr->bottom_type(); | |
3240 const Type* t2 = val->bottom_type(); | |
3241 | |
3242 Node* orig = __ load(no_ctrl, adr, val_type, bt, alias_idx); | |
3243 // if (orig != NULL) | |
3244 __ if_then(orig, BoolTest::ne, null()); { | |
3245 | |
3246 // load original value | |
3247 // alias_idx correct?? | |
3248 | |
3249 // is the queue for this thread full? | |
3250 __ if_then(index, BoolTest::ne, zero, likely); { | |
3251 | |
3252 // decrement the index | |
3253 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); | |
3254 Node* next_indexX = next_index; | |
3255 #ifdef _LP64 | |
3256 // We could refine the type for what it's worth | |
3257 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); | |
3258 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); | |
3259 #endif // _LP64 | |
3260 | |
3261 // Now get the buffer location we will log the original value into and store it | |
3262 | |
3263 Node *log_addr = __ AddP(no_base, buffer, next_indexX); | |
3264 // __ store(__ ctrl(), log_addr, orig, T_OBJECT, C->get_alias_index(TypeOopPtr::BOTTOM)); | |
3265 __ store(__ ctrl(), log_addr, orig, T_OBJECT, Compile::AliasIdxRaw); | |
3266 | |
3267 | |
3268 // update the index | |
3269 // __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); | |
3270 // This is a hack to force this store to occur before the oop store that is coming up | |
3271 __ store(__ ctrl(), index_adr, next_index, T_INT, C->get_alias_index(TypeOopPtr::BOTTOM)); | |
3272 | |
3273 } __ else_(); { | |
3274 | |
3275 // logging buffer is full, call the runtime | |
3276 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); | |
3277 // __ make_leaf_call(tf, OptoRuntime::g1_wb_pre_Java(), "g1_wb_pre", orig, thread); | |
3278 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", orig, thread); | |
3279 } __ end_if(); | |
3280 } __ end_if(); | |
3281 } __ end_if(); | |
3282 | |
3283 __ drain_delay_transform(); | |
3284 set_control( __ ctrl()); | |
3285 set_all_memory( __ merged_memory()); | |
3286 | |
3287 #undef __ | |
3288 } | |
3289 | |
3290 // | |
3291 // Update the card table and add card address to the queue | |
3292 // | |
3293 void GraphKit::g1_mark_card(IdealKit* ideal, Node* card_adr, Node* store, Node* index, Node* index_adr, Node* buffer, const TypeFunc* tf) { | |
3294 #define __ ideal-> | |
3295 Node* zero = __ ConI(0); | |
3296 Node* no_base = __ top(); | |
3297 BasicType card_bt = T_BYTE; | |
3298 // Smash zero into card. MUST BE ORDERED WRT TO STORE | |
3299 __ storeCM(__ ctrl(), card_adr, zero, store, card_bt, Compile::AliasIdxRaw); | |
3300 | |
3301 // Now do the queue work | |
3302 __ if_then(index, BoolTest::ne, zero); { | |
3303 | |
3304 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); | |
3305 Node* next_indexX = next_index; | |
3306 #ifdef _LP64 | |
3307 // We could refine the type for what it's worth | |
3308 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); | |
3309 next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); | |
3310 #endif // _LP64 | |
3311 Node* log_addr = __ AddP(no_base, buffer, next_indexX); | |
3312 | |
3313 __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw); | |
3314 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); | |
3315 | |
3316 } __ else_(); { | |
3317 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread()); | |
3318 } __ end_if(); | |
3319 #undef __ | |
3320 } | |
3321 | |
3322 void GraphKit::g1_write_barrier_post(Node* store, | |
3323 Node* obj, | |
3324 Node* adr, | |
3325 uint alias_idx, | |
3326 Node* val, | |
3327 BasicType bt, | |
3328 bool use_precise) { | |
3329 // If we are writing a NULL then we need no post barrier | |
3330 | |
3331 if (val != NULL && val->is_Con() && val->bottom_type() == TypePtr::NULL_PTR) { | |
3332 // Must be NULL | |
3333 const Type* t = val->bottom_type(); | |
3334 assert(t == Type::TOP || t == TypePtr::NULL_PTR, "must be NULL"); | |
3335 // No post barrier if writing NULLx | |
3336 return; | |
3337 } | |
3338 | |
3339 if (!use_precise) { | |
3340 // All card marks for a (non-array) instance are in one place: | |
3341 adr = obj; | |
3342 } | |
3343 // (Else it's an array (or unknown), and we want more precise card marks.) | |
3344 assert(adr != NULL, ""); | |
3345 | |
3346 IdealKit ideal(gvn(), control(), merged_memory(), true); | |
3347 #define __ ideal. | |
3348 __ declares_done(); | |
3349 | |
3350 Node* thread = __ thread(); | |
3351 | |
3352 Node* no_ctrl = NULL; | |
3353 Node* no_base = __ top(); | |
3354 float likely = PROB_LIKELY(0.999); | |
3355 float unlikely = PROB_UNLIKELY(0.999); | |
3356 Node* zero = __ ConI(0); | |
3357 Node* zeroX = __ ConX(0); | |
3358 | |
3359 // Get the alias_index for raw card-mark memory | |
3360 const TypePtr* card_type = TypeRawPtr::BOTTOM; | |
3361 | |
3362 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type(); | |
3363 | |
3364 // Get the address of the card table | |
3365 CardTableModRefBS* ct = | |
3366 (CardTableModRefBS*)(Universe::heap()->barrier_set()); | |
3367 Node *card_table = __ makecon(TypeRawPtr::make((address)ct->byte_map_base)); | |
3368 // Get base of card map | |
3369 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); | |
3370 | |
3371 | |
3372 // Offsets into the thread | |
3373 const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() + | |
3374 PtrQueue::byte_offset_of_index()); | |
3375 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() + | |
3376 PtrQueue::byte_offset_of_buf()); | |
3377 | |
3378 // Pointers into the thread | |
3379 | |
3380 Node* buffer_adr = __ AddP(no_base, thread, __ ConX(buffer_offset)); | |
3381 Node* index_adr = __ AddP(no_base, thread, __ ConX(index_offset)); | |
3382 | |
3383 // Now some values | |
3384 | |
3385 Node* index = __ load(no_ctrl, index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); | |
3386 Node* buffer = __ load(no_ctrl, buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); | |
3387 | |
3388 | |
3389 // Convert the store obj pointer to an int prior to doing math on it | |
3390 // Use addr not obj gets accurate card marks | |
3391 | |
3392 // Node* cast = __ CastPX(no_ctrl, adr /* obj */); | |
3393 | |
3394 // Must use ctrl to prevent "integerized oop" existing across safepoint | |
3395 Node* cast = __ CastPX(__ ctrl(), ( use_precise ? adr : obj )); | |
3396 | |
3397 // Divide pointer by card size | |
3398 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) ); | |
3399 | |
3400 // Combine card table base and card offset | |
3401 Node *card_adr = __ AddP(no_base, card_table, card_offset ); | |
3402 | |
3403 // If we know the value being stored does it cross regions? | |
3404 | |
3405 if (val != NULL) { | |
3406 // Does the store cause us to cross regions? | |
3407 | |
3408 // Should be able to do an unsigned compare of region_size instead of | |
3409 // and extra shift. Do we have an unsigned compare?? | |
3410 // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes); | |
3411 Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes)); | |
3412 | |
3413 // if (xor_res == 0) same region so skip | |
3414 __ if_then(xor_res, BoolTest::ne, zeroX); { | |
3415 | |
3416 // No barrier if we are storing a NULL | |
3417 __ if_then(val, BoolTest::ne, null(), unlikely); { | |
3418 | |
3419 // Ok must mark the card if not already dirty | |
3420 | |
3421 // load the original value of the card | |
3422 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw); | |
3423 | |
3424 __ if_then(card_val, BoolTest::ne, zero); { | |
3425 g1_mark_card(&ideal, card_adr, store, index, index_adr, buffer, tf); | |
3426 } __ end_if(); | |
3427 } __ end_if(); | |
3428 } __ end_if(); | |
3429 } else { | |
3430 g1_mark_card(&ideal, card_adr, store, index, index_adr, buffer, tf); | |
3431 } | |
3432 | |
3433 | |
3434 __ drain_delay_transform(); | |
3435 set_control( __ ctrl()); | |
3436 set_all_memory( __ merged_memory()); | |
3437 #undef __ | |
3438 | |
3439 } |