Mercurial > hg > truffle
comparison src/share/vm/opto/library_call.cpp @ 8883:b9a918201d47
Merge with hsx25
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Sat, 06 Apr 2013 20:04:06 +0200 |
parents | 16885e702c88 |
children | 124ca22437b1 |
comparison
equal
deleted
inserted
replaced
8660:d47b52b0ff68 | 8883:b9a918201d47 |
---|---|
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; |