src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp

changeset 1079
c517646eef23
parent 791
1ee8caae33af
child 1100
c89f86385056
equal deleted inserted replaced
1078:c771b7f43bbf 1079:c517646eef23
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

mercurial