2391 load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); |
2391 load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); |
2392 load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
2392 load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
2393 |
2393 |
2394 // get instance klass |
2394 // get instance klass |
2395 load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); |
2395 load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); |
2396 // get super_check_offset |
2396 // perform the fast part of the checking logic |
2397 load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1, T_INT, NULL); |
2397 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done, stub->entry(), NULL); |
2398 // See if we get an immediate positive hit |
2398 |
2399 __ ld_ptr(klass_RInfo, Rtmp1, FrameMap::O7_oop_opr->as_register()); |
2399 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2400 __ cmp(k_RInfo, O7); |
2400 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2401 __ br(Assembler::equal, false, Assembler::pn, done); |
|
2402 __ delayed()->nop(); |
|
2403 // check for immediate negative hit |
|
2404 __ cmp(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); |
|
2405 __ br(Assembler::notEqual, false, Assembler::pn, *stub->entry()); |
|
2406 __ delayed()->nop(); |
|
2407 // check for self |
|
2408 __ cmp(klass_RInfo, k_RInfo); |
|
2409 __ br(Assembler::equal, false, Assembler::pn, done); |
|
2410 __ delayed()->nop(); |
|
2411 |
|
2412 // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); |
|
2413 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2401 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2414 __ delayed()->nop(); |
2402 __ delayed()->nop(); |
2415 __ cmp(G3, 0); |
2403 __ cmp(G3, 0); |
2416 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2404 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2417 __ delayed()->nop(); |
2405 __ delayed()->nop(); |
2491 __ cmp(k_RInfo, klass_RInfo); |
2479 __ cmp(k_RInfo, klass_RInfo); |
2492 __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); |
2480 __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry()); |
2493 __ delayed()->nop(); |
2481 __ delayed()->nop(); |
2494 __ bind(done); |
2482 __ bind(done); |
2495 } else { |
2483 } else { |
|
2484 bool need_slow_path = true; |
2496 if (k->is_loaded()) { |
2485 if (k->is_loaded()) { |
2497 load(klass_RInfo, k->super_check_offset(), Rtmp1, T_OBJECT, NULL); |
2486 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) |
2498 |
2487 need_slow_path = false; |
2499 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { |
2488 // perform the fast part of the checking logic |
2500 // See if we get an immediate positive hit |
2489 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg, |
2501 __ cmp(Rtmp1, k_RInfo ); |
2490 (need_slow_path ? &done : NULL), |
2502 __ br(Assembler::notEqual, false, Assembler::pn, *stub->entry()); |
2491 stub->entry(), NULL, |
2503 __ delayed()->nop(); |
2492 RegisterConstant(k->super_check_offset())); |
2504 } else { |
|
2505 // See if we get an immediate positive hit |
|
2506 assert_different_registers(Rtmp1, k_RInfo, klass_RInfo); |
|
2507 __ cmp(Rtmp1, k_RInfo ); |
|
2508 __ br(Assembler::equal, false, Assembler::pn, done); |
|
2509 // check for self |
|
2510 __ delayed()->cmp(klass_RInfo, k_RInfo); |
|
2511 __ br(Assembler::equal, false, Assembler::pn, done); |
|
2512 __ delayed()->nop(); |
|
2513 |
|
2514 // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); |
|
2515 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
|
2516 __ delayed()->nop(); |
|
2517 __ cmp(G3, 0); |
|
2518 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); |
|
2519 __ delayed()->nop(); |
|
2520 } |
|
2521 __ bind(done); |
|
2522 } else { |
2493 } else { |
2523 assert_different_registers(Rtmp1, klass_RInfo, k_RInfo); |
2494 // perform the fast part of the checking logic |
2524 |
2495 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, |
2525 load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), Rtmp1, T_INT, NULL); |
2496 &done, stub->entry(), NULL); |
2526 // See if we get an immediate positive hit |
2497 } |
2527 load(klass_RInfo, Rtmp1, FrameMap::O7_oop_opr, T_OBJECT); |
2498 if (need_slow_path) { |
2528 __ cmp(k_RInfo, O7); |
2499 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2529 __ br(Assembler::equal, false, Assembler::pn, done); |
2500 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2530 __ delayed()->nop(); |
|
2531 // check for immediate negative hit |
|
2532 __ cmp(Rtmp1, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); |
|
2533 __ br(Assembler::notEqual, false, Assembler::pn, *stub->entry()); |
|
2534 // check for self |
|
2535 __ delayed()->cmp(klass_RInfo, k_RInfo); |
|
2536 __ br(Assembler::equal, false, Assembler::pn, done); |
|
2537 __ delayed()->nop(); |
|
2538 |
|
2539 // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); |
|
2540 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2501 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2541 __ delayed()->nop(); |
2502 __ delayed()->nop(); |
2542 __ cmp(G3, 0); |
2503 __ cmp(G3, 0); |
2543 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2504 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2544 __ delayed()->nop(); |
2505 __ delayed()->nop(); |
2545 __ bind(done); |
2506 } |
2546 } |
2507 __ bind(done); |
2547 |
|
2548 } |
2508 } |
2549 __ mov(obj, dst); |
2509 __ mov(obj, dst); |
2550 } else if (code == lir_instanceof) { |
2510 } else if (code == lir_instanceof) { |
2551 Register obj = op->object()->as_register(); |
2511 Register obj = op->object()->as_register(); |
2552 Register k_RInfo = op->tmp1()->as_register(); |
2512 Register k_RInfo = op->tmp1()->as_register(); |
2580 __ br(Assembler::equal, true, Assembler::pt, done); |
2540 __ br(Assembler::equal, true, Assembler::pt, done); |
2581 __ delayed()->set(1, dst); |
2541 __ delayed()->set(1, dst); |
2582 __ set(0, dst); |
2542 __ set(0, dst); |
2583 __ bind(done); |
2543 __ bind(done); |
2584 } else { |
2544 } else { |
|
2545 bool need_slow_path = true; |
2585 if (k->is_loaded()) { |
2546 if (k->is_loaded()) { |
2586 assert_different_registers(Rtmp1, klass_RInfo, k_RInfo); |
2547 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) |
2587 load(klass_RInfo, k->super_check_offset(), Rtmp1, T_OBJECT, NULL); |
2548 need_slow_path = false; |
2588 |
2549 // perform the fast part of the checking logic |
2589 if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { |
2550 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, noreg, |
2590 // See if we get an immediate positive hit |
2551 (need_slow_path ? &done : NULL), |
2591 __ cmp(Rtmp1, k_RInfo ); |
2552 (need_slow_path ? &done : NULL), NULL, |
2592 __ br(Assembler::equal, true, Assembler::pt, done); |
2553 RegisterConstant(k->super_check_offset()), |
2593 __ delayed()->set(1, dst); |
2554 dst); |
2594 __ set(0, dst); |
|
2595 __ bind(done); |
|
2596 } else { |
|
2597 // See if we get an immediate positive hit |
|
2598 assert_different_registers(Rtmp1, k_RInfo, klass_RInfo); |
|
2599 __ cmp(Rtmp1, k_RInfo ); |
|
2600 __ br(Assembler::equal, true, Assembler::pt, done); |
|
2601 __ delayed()->set(1, dst); |
|
2602 // check for self |
|
2603 __ cmp(klass_RInfo, k_RInfo); |
|
2604 __ br(Assembler::equal, true, Assembler::pt, done); |
|
2605 __ delayed()->set(1, dst); |
|
2606 |
|
2607 // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); |
|
2608 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
|
2609 __ delayed()->nop(); |
|
2610 __ mov(G3, dst); |
|
2611 __ bind(done); |
|
2612 } |
|
2613 } else { |
2555 } else { |
2614 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); |
2556 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); |
2615 |
2557 // perform the fast part of the checking logic |
2616 load(k_RInfo, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes(), dst, T_INT, NULL); |
2558 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, dst, |
2617 // See if we get an immediate positive hit |
2559 &done, &done, NULL, |
2618 load(klass_RInfo, dst, FrameMap::O7_oop_opr, T_OBJECT); |
2560 RegisterConstant(-1), |
2619 __ cmp(k_RInfo, O7); |
2561 dst); |
2620 __ br(Assembler::equal, true, Assembler::pt, done); |
2562 } |
2621 __ delayed()->set(1, dst); |
2563 if (need_slow_path) { |
2622 // check for immediate negative hit |
2564 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2623 __ cmp(dst, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); |
2565 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2624 __ br(Assembler::notEqual, true, Assembler::pt, done); |
|
2625 __ delayed()->set(0, dst); |
|
2626 // check for self |
|
2627 __ cmp(klass_RInfo, k_RInfo); |
|
2628 __ br(Assembler::equal, true, Assembler::pt, done); |
|
2629 __ delayed()->set(1, dst); |
|
2630 |
|
2631 // assert(sub.is_same(FrameMap::G3_RInfo) && super.is_same(FrameMap::G1_RInfo), "incorrect call setup"); |
|
2632 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2566 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2633 __ delayed()->nop(); |
2567 __ delayed()->nop(); |
2634 __ mov(G3, dst); |
2568 __ mov(G3, dst); |
2635 __ bind(done); |
2569 } |
2636 } |
2570 __ bind(done); |
2637 } |
2571 } |
2638 } else { |
2572 } else { |
2639 ShouldNotReachHere(); |
2573 ShouldNotReachHere(); |
2640 } |
2574 } |
2641 |
2575 |