comparison src/share/vm/opto/library_call.cpp @ 8866:16885e702c88

7198429: need checked categorization of caller-sensitive methods in the JDK Reviewed-by: kvn, jrose
author twisti
date Mon, 25 Mar 2013 17:13:26 -0700
parents c59b7900a2bd
children 124ca22437b1
comparison
equal deleted inserted replaced
8865:818a1ac7da7a 8866:16885e702c88
229 bool inline_array_copyOf(bool is_copyOfRange); 229 bool inline_array_copyOf(bool is_copyOfRange);
230 bool inline_array_equals(); 230 bool inline_array_equals();
231 void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark); 231 void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
232 bool inline_native_clone(bool is_virtual); 232 bool inline_native_clone(bool is_virtual);
233 bool inline_native_Reflection_getCallerClass(); 233 bool inline_native_Reflection_getCallerClass();
234 bool is_method_invoke_or_aux_frame(JVMState* jvms);
235 // Helper function for inlining native object hash method 234 // Helper function for inlining native object hash method
236 bool inline_native_hashcode(bool is_virtual, bool is_static); 235 bool inline_native_hashcode(bool is_virtual, bool is_static);
237 bool inline_native_getClass(); 236 bool inline_native_getClass();
238 237
239 // Helper functions for inlining arraycopy 238 // Helper functions for inlining arraycopy
391 return NULL; 390 return NULL;
392 391
393 case vmIntrinsics::_getCallerClass: 392 case vmIntrinsics::_getCallerClass:
394 if (!UseNewReflection) return NULL; 393 if (!UseNewReflection) return NULL;
395 if (!InlineReflectionGetCallerClass) return NULL; 394 if (!InlineReflectionGetCallerClass) return NULL;
396 if (!JDK_Version::is_gte_jdk14x_version()) return NULL; 395 if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL;
397 break; 396 break;
398 397
399 case vmIntrinsics::_bitCount_i: 398 case vmIntrinsics::_bitCount_i:
400 if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL; 399 if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL;
401 break; 400 break;
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;