src/share/vm/ci/ciMethod.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/ci

src/share/vm/ci/ciMethod.cpp

Print this page
rev 6132 : 8031755: Type speculation should be used to optimize explicit null checks
Summary: feed profiling data about reference nullness to type speculation.
Reviewed-by:


 564   _receiver_count[i] = receiver_count;
 565   if (_limit < MorphismLimit) _limit++;
 566 }
 567 
 568 
 569 void ciMethod::assert_virtual_call_type_ok(int bci) {
 570   assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual ||
 571          java_code_at_bci(bci) == Bytecodes::_invokeinterface, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
 572 }
 573 
 574 void ciMethod::assert_call_type_ok(int bci) {
 575   assert(java_code_at_bci(bci) == Bytecodes::_invokestatic ||
 576          java_code_at_bci(bci) == Bytecodes::_invokespecial ||
 577          java_code_at_bci(bci) == Bytecodes::_invokedynamic, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
 578 }
 579 
 580 /**
 581  * Check whether profiling provides a type for the argument i to the
 582  * call at bci bci
 583  *
 584  * @param bci  bci of the call
 585  * @param i    argument number
 586  * @return     profiled type


 587  *
 588  * If the profile reports that the argument may be null, return false
 589  * at least for now.
 590  */
 591 ciKlass* ciMethod::argument_profiled_type(int bci, int i) {
 592   if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
 593     ciProfileData* data = method_data()->bci_to_data(bci);
 594     if (data != NULL) {
 595       if (data->is_VirtualCallTypeData()) {
 596         assert_virtual_call_type_ok(bci);
 597         ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
 598         if (i >= call->number_of_arguments()) {
 599           return NULL;
 600         }
 601         ciKlass* type = call->valid_argument_type(i);
 602         if (type != NULL && !call->argument_maybe_null(i)) {
 603           return type;
 604         }



 605       } else if (data->is_CallTypeData()) {
 606         assert_call_type_ok(bci);
 607         ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
 608         if (i >= call->number_of_arguments()) {
 609           return NULL;
 610         }
 611         ciKlass* type = call->valid_argument_type(i);
 612         if (type != NULL && !call->argument_maybe_null(i)) {
 613           return type;
 614         }



 615       }
 616     }
 617   }
 618   return NULL;
 619 }
 620 
 621 /**
 622  * Check whether profiling provides a type for the return value from
 623  * the call at bci bci
 624  *
 625  * @param bci  bci of the call
 626  * @return     profiled type


 627  *
 628  * If the profile reports that the argument may be null, return false
 629  * at least for now.
 630  */
 631 ciKlass* ciMethod::return_profiled_type(int bci) {
 632   if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) {
 633     ciProfileData* data = method_data()->bci_to_data(bci);
 634     if (data != NULL) {
 635       if (data->is_VirtualCallTypeData()) {
 636         assert_virtual_call_type_ok(bci);
 637         ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
 638         ciKlass* type = call->valid_return_type();
 639         if (type != NULL && !call->return_maybe_null()) {
 640           return type;
 641         }
 642       } else if (data->is_CallTypeData()) {
 643         assert_call_type_ok(bci);
 644         ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
 645         ciKlass* type = call->valid_return_type();
 646         if (type != NULL && !call->return_maybe_null()) {
 647           return type;
 648         }
 649       }
 650     }
 651   }
 652   return NULL;
 653 }
 654 
 655 /**
 656  * Check whether profiling provides a type for the parameter i
 657  *
 658  * @param i    parameter number
 659  * @return     profiled type


 660  *
 661  * If the profile reports that the argument may be null, return false
 662  * at least for now.
 663  */
 664 ciKlass* ciMethod::parameter_profiled_type(int i) {
 665   if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
 666     ciParametersTypeData* parameters = method_data()->parameters_type_data();
 667     if (parameters != NULL && i < parameters->number_of_parameters()) {
 668       ciKlass* type = parameters->valid_parameter_type(i);
 669       if (type != NULL && !parameters->parameter_maybe_null(i)) {
 670         return type;
 671       }
 672     }
 673   }
 674   return NULL;
 675 }
 676 
 677 
 678 // ------------------------------------------------------------------
 679 // ciMethod::find_monomorphic_target
 680 //
 681 // Given a certain calling environment, find the monomorphic target
 682 // for the call.  Return NULL if the call is not monomorphic in
 683 // its calling environment, or if there are only abstract methods.
 684 // The returned method is never abstract.
 685 // Note: If caller uses a non-null result, it must inform dependencies
 686 // via assert_unique_concrete_method or assert_leaf_type.
 687 ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
 688                                             ciInstanceKlass* callee_holder,
 689                                             ciInstanceKlass* actual_recv) {
 690   check_is_loaded();
 691 
 692   if (actual_recv->is_interface()) {
 693     // %%% We cannot trust interface types, yet.  See bug 6312651.
 694     return NULL;




 564   _receiver_count[i] = receiver_count;
 565   if (_limit < MorphismLimit) _limit++;
 566 }
 567 
 568 
 569 void ciMethod::assert_virtual_call_type_ok(int bci) {
 570   assert(java_code_at_bci(bci) == Bytecodes::_invokevirtual ||
 571          java_code_at_bci(bci) == Bytecodes::_invokeinterface, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
 572 }
 573 
 574 void ciMethod::assert_call_type_ok(int bci) {
 575   assert(java_code_at_bci(bci) == Bytecodes::_invokestatic ||
 576          java_code_at_bci(bci) == Bytecodes::_invokespecial ||
 577          java_code_at_bci(bci) == Bytecodes::_invokedynamic, err_msg("unexpected bytecode %s", Bytecodes::name(java_code_at_bci(bci))));
 578 }
 579 
 580 /**
 581  * Check whether profiling provides a type for the argument i to the
 582  * call at bci bci
 583  *
 584  * @param [in]bci         bci of the call
 585  * @param [in]i           argument number
 586  * @param [out]type       profiled type of argument, NULL if none
 587  * @param [out]maybe_null true if null was seen for argument
 588  * @return                true if profiling exists
 589  *


 590  */
 591 bool ciMethod::argument_profiled_type(int bci, int i, ciKlass*& type, bool& maybe_null) {
 592   if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
 593     ciProfileData* data = method_data()->bci_to_data(bci);
 594     if (data != NULL) {
 595       if (data->is_VirtualCallTypeData()) {
 596         assert_virtual_call_type_ok(bci);
 597         ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
 598         if (i >= call->number_of_arguments()) {
 599           return false;




 600         }
 601         type = call->valid_argument_type(i);
 602         maybe_null = call->argument_maybe_null(i);
 603         return true;
 604       } else if (data->is_CallTypeData()) {
 605         assert_call_type_ok(bci);
 606         ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
 607         if (i >= call->number_of_arguments()) {
 608           return false;




 609         }
 610         type = call->valid_argument_type(i);
 611         maybe_null = call->argument_maybe_null(i);
 612         return true;
 613       }
 614     }
 615   }
 616   return false;
 617 }
 618 
 619 /**
 620  * Check whether profiling provides a type for the return value from
 621  * the call at bci bci
 622  *
 623  * @param [in]bci         bci of the call
 624  * @param [out]type       profiled type of argument, NULL if none
 625  * @param [out]maybe_null true if null was seen for argument
 626  * @return                true if profiling exists
 627  *


 628  */
 629 bool ciMethod::return_profiled_type(int bci, ciKlass*& type, bool& maybe_null) {
 630   if (MethodData::profile_return() && method_data() != NULL && method_data()->is_mature()) {
 631     ciProfileData* data = method_data()->bci_to_data(bci);
 632     if (data != NULL) {
 633       if (data->is_VirtualCallTypeData()) {
 634         assert_virtual_call_type_ok(bci);
 635         ciVirtualCallTypeData* call = (ciVirtualCallTypeData*)data->as_VirtualCallTypeData();
 636         type = call->valid_return_type();
 637         maybe_null = call->return_maybe_null();
 638         return true;

 639       } else if (data->is_CallTypeData()) {
 640         assert_call_type_ok(bci);
 641         ciCallTypeData* call = (ciCallTypeData*)data->as_CallTypeData();
 642         type = call->valid_return_type();
 643         maybe_null = call->return_maybe_null();
 644         return true;
 645       }
 646     }
 647   }
 648   return false;

 649 }
 650 
 651 /**
 652  * Check whether profiling provides a type for the parameter i
 653  *
 654  * @param [in]i           parameter number
 655  * @param [out]type       profiled type of parameter, NULL if none
 656  * @param [out]maybe_null true if null was seen for parameter
 657  * @return                true if profiling exists
 658  *


 659  */
 660 bool ciMethod::parameter_profiled_type(int i, ciKlass*& type, bool& maybe_null) {
 661   if (MethodData::profile_parameters() && method_data() != NULL && method_data()->is_mature()) {
 662     ciParametersTypeData* parameters = method_data()->parameters_type_data();
 663     if (parameters != NULL && i < parameters->number_of_parameters()) {
 664       type = parameters->valid_parameter_type(i);
 665       maybe_null = parameters->parameter_maybe_null(i);
 666       return true;

 667     }
 668   }
 669   return false;
 670 }
 671 
 672 
 673 // ------------------------------------------------------------------
 674 // ciMethod::find_monomorphic_target
 675 //
 676 // Given a certain calling environment, find the monomorphic target
 677 // for the call.  Return NULL if the call is not monomorphic in
 678 // its calling environment, or if there are only abstract methods.
 679 // The returned method is never abstract.
 680 // Note: If caller uses a non-null result, it must inform dependencies
 681 // via assert_unique_concrete_method or assert_leaf_type.
 682 ciMethod* ciMethod::find_monomorphic_target(ciInstanceKlass* caller,
 683                                             ciInstanceKlass* callee_holder,
 684                                             ciInstanceKlass* actual_recv) {
 685   check_is_loaded();
 686 
 687   if (actual_recv->is_interface()) {
 688     // %%% We cannot trust interface types, yet.  See bug 6312651.
 689     return NULL;


src/share/vm/ci/ciMethod.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File