3870 set_result(load_mirror_from_klass(load_object_klass(obj))); |
3869 set_result(load_mirror_from_klass(load_object_klass(obj))); |
3871 return true; |
3870 return true; |
3872 } |
3871 } |
3873 |
3872 |
3874 //-----------------inline_native_Reflection_getCallerClass--------------------- |
3873 //-----------------inline_native_Reflection_getCallerClass--------------------- |
3875 // public static native Class<?> sun.reflect.Reflection.getCallerClass(int realFramesToSkip); |
3874 // public static native Class<?> sun.reflect.Reflection.getCallerClass(); |
3876 // |
3875 // |
3877 // In the presence of deep enough inlining, getCallerClass() becomes a no-op. |
3876 // In the presence of deep enough inlining, getCallerClass() becomes a no-op. |
3878 // |
3877 // |
3879 // NOTE that this code must perform the same logic as |
3878 // NOTE: This code must perform the same logic as JVM_GetCallerClass |
3880 // vframeStream::security_get_caller_frame in that it must skip |
3879 // in that it must skip particular security frames and checks for |
3881 // Method.invoke() and auxiliary frames. |
3880 // caller sensitive methods. |
3882 bool LibraryCallKit::inline_native_Reflection_getCallerClass() { |
3881 bool LibraryCallKit::inline_native_Reflection_getCallerClass() { |
3883 #ifndef PRODUCT |
3882 #ifndef PRODUCT |
3884 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3883 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3885 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); |
3884 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); |
3886 } |
3885 } |
3887 #endif |
3886 #endif |
3888 |
3887 |
3889 Node* caller_depth_node = argument(0); |
|
3890 |
|
3891 // The depth value must be a constant in order for the runtime call |
|
3892 // to be eliminated. |
|
3893 const TypeInt* caller_depth_type = _gvn.type(caller_depth_node)->isa_int(); |
|
3894 if (caller_depth_type == NULL || !caller_depth_type->is_con()) { |
|
3895 #ifndef PRODUCT |
|
3896 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
|
3897 tty->print_cr(" Bailing out because caller depth was not a constant"); |
|
3898 } |
|
3899 #endif |
|
3900 return false; |
|
3901 } |
|
3902 // Note that the JVM state at this point does not include the |
|
3903 // getCallerClass() frame which we are trying to inline. The |
|
3904 // semantics of getCallerClass(), however, are that the "first" |
|
3905 // frame is the getCallerClass() frame, so we subtract one from the |
|
3906 // requested depth before continuing. We don't inline requests of |
|
3907 // getCallerClass(0). |
|
3908 int caller_depth = caller_depth_type->get_con() - 1; |
|
3909 if (caller_depth < 0) { |
|
3910 #ifndef PRODUCT |
|
3911 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
|
3912 tty->print_cr(" Bailing out because caller depth was %d", caller_depth); |
|
3913 } |
|
3914 #endif |
|
3915 return false; |
|
3916 } |
|
3917 |
|
3918 if (!jvms()->has_method()) { |
3888 if (!jvms()->has_method()) { |
3919 #ifndef PRODUCT |
3889 #ifndef PRODUCT |
3920 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3890 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3921 tty->print_cr(" Bailing out because intrinsic was inlined at top level"); |
3891 tty->print_cr(" Bailing out because intrinsic was inlined at top level"); |
3922 } |
3892 } |
3923 #endif |
3893 #endif |
3924 return false; |
3894 return false; |
3925 } |
3895 } |
3926 int _depth = jvms()->depth(); // cache call chain depth |
|
3927 |
3896 |
3928 // Walk back up the JVM state to find the caller at the required |
3897 // Walk back up the JVM state to find the caller at the required |
3929 // depth. NOTE that this code must perform the same logic as |
3898 // depth. |
3930 // vframeStream::security_get_caller_frame in that it must skip |
3899 JVMState* caller_jvms = jvms(); |
3931 // Method.invoke() and auxiliary frames. Note also that depth is |
3900 |
3932 // 1-based (1 is the bottom of the inlining). |
3901 // Cf. JVM_GetCallerClass |
3933 int inlining_depth = _depth; |
3902 // NOTE: Start the loop at depth 1 because the current JVM state does |
3934 JVMState* caller_jvms = NULL; |
3903 // not include the Reflection.getCallerClass() frame. |
3935 |
3904 for (int n = 1; caller_jvms != NULL; caller_jvms = caller_jvms->caller(), n++) { |
3936 if (inlining_depth > 0) { |
3905 ciMethod* m = caller_jvms->method(); |
3937 caller_jvms = jvms(); |
3906 switch (n) { |
3938 assert(caller_jvms = jvms()->of_depth(inlining_depth), "inlining_depth == our depth"); |
3907 case 0: |
3939 do { |
3908 fatal("current JVM state does not include the Reflection.getCallerClass frame"); |
3940 // The following if-tests should be performed in this order |
3909 break; |
3941 if (is_method_invoke_or_aux_frame(caller_jvms)) { |
3910 case 1: |
3942 // Skip a Method.invoke() or auxiliary frame |
3911 // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). |
3943 } else if (caller_depth > 0) { |
3912 if (!m->caller_sensitive()) { |
3944 // Skip real frame |
3913 #ifndef PRODUCT |
3945 --caller_depth; |
3914 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3946 } else { |
3915 tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n); |
3947 // We're done: reached desired caller after skipping. |
3916 } |
3948 break; |
3917 #endif |
|
3918 return false; // bail-out; let JVM_GetCallerClass do the work |
3949 } |
3919 } |
3950 caller_jvms = caller_jvms->caller(); |
3920 break; |
3951 --inlining_depth; |
3921 default: |
3952 } while (inlining_depth > 0); |
3922 if (!m->is_ignored_by_security_stack_walk()) { |
3953 } |
3923 // We have reached the desired frame; return the holder class. |
3954 |
3924 // Acquire method holder as java.lang.Class and push as constant. |
3955 if (inlining_depth == 0) { |
3925 ciInstanceKlass* caller_klass = caller_jvms->method()->holder(); |
|
3926 ciInstance* caller_mirror = caller_klass->java_mirror(); |
|
3927 set_result(makecon(TypeInstPtr::make(caller_mirror))); |
|
3928 |
3956 #ifndef PRODUCT |
3929 #ifndef PRODUCT |
3957 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3930 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3958 tty->print_cr(" Bailing out because caller depth (%d) exceeded inlining depth (%d)", caller_depth_type->get_con(), _depth); |
3931 tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth()); |
3959 tty->print_cr(" JVM state at this point:"); |
3932 tty->print_cr(" JVM state at this point:"); |
3960 for (int i = _depth; i >= 1; i--) { |
3933 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { |
3961 ciMethod* m = jvms()->of_depth(i)->method(); |
3934 ciMethod* m = jvms()->of_depth(i)->method(); |
3962 tty->print_cr(" %d) %s.%s", i, m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
3935 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
|
3936 } |
|
3937 } |
|
3938 #endif |
|
3939 return true; |
3963 } |
3940 } |
3964 } |
3941 break; |
3965 #endif |
3942 } |
3966 return false; // Reached end of inlining |
3943 } |
3967 } |
|
3968 |
|
3969 // Acquire method holder as java.lang.Class |
|
3970 ciInstanceKlass* caller_klass = caller_jvms->method()->holder(); |
|
3971 ciInstance* caller_mirror = caller_klass->java_mirror(); |
|
3972 |
|
3973 // Push this as a constant |
|
3974 set_result(makecon(TypeInstPtr::make(caller_mirror))); |
|
3975 |
3944 |
3976 #ifndef PRODUCT |
3945 #ifndef PRODUCT |
3977 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3946 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { |
3978 tty->print_cr(" Succeeded: caller = %s.%s, caller depth = %d, depth = %d", caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), caller_depth_type->get_con(), _depth); |
3947 tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth()); |
3979 tty->print_cr(" JVM state at this point:"); |
3948 tty->print_cr(" JVM state at this point:"); |
3980 for (int i = _depth; i >= 1; i--) { |
3949 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { |
3981 ciMethod* m = jvms()->of_depth(i)->method(); |
3950 ciMethod* m = jvms()->of_depth(i)->method(); |
3982 tty->print_cr(" %d) %s.%s", i, m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
3951 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
3983 } |
3952 } |
3984 } |
3953 } |
3985 #endif |
3954 #endif |
3986 return true; |
3955 |
3987 } |
3956 return false; // bail-out; let JVM_GetCallerClass do the work |
3988 |
|
3989 // Helper routine for above |
|
3990 bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) { |
|
3991 ciMethod* method = jvms->method(); |
|
3992 |
|
3993 // Is this the Method.invoke method itself? |
|
3994 if (method->intrinsic_id() == vmIntrinsics::_invoke) |
|
3995 return true; |
|
3996 |
|
3997 // Is this a helper, defined somewhere underneath MethodAccessorImpl. |
|
3998 ciKlass* k = method->holder(); |
|
3999 if (k->is_instance_klass()) { |
|
4000 ciInstanceKlass* ik = k->as_instance_klass(); |
|
4001 for (; ik != NULL; ik = ik->super()) { |
|
4002 if (ik->name() == ciSymbol::sun_reflect_MethodAccessorImpl() && |
|
4003 ik == env()->find_system_klass(ik->name())) { |
|
4004 return true; |
|
4005 } |
|
4006 } |
|
4007 } |
|
4008 else if (method->is_method_handle_intrinsic() || |
|
4009 method->is_compiled_lambda_form()) { |
|
4010 // This is an internal adapter frame from the MethodHandleCompiler -- skip it |
|
4011 return true; |
|
4012 } |
|
4013 |
|
4014 return false; |
|
4015 } |
3957 } |
4016 |
3958 |
4017 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) { |
3959 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) { |
4018 Node* arg = argument(0); |
3960 Node* arg = argument(0); |
4019 Node* result; |
3961 Node* result; |