48 #include "oops/verifyOopClosure.hpp" |
48 #include "oops/verifyOopClosure.hpp" |
49 #include "prims/jvmtiThreadState.hpp" |
49 #include "prims/jvmtiThreadState.hpp" |
50 #include "runtime/biasedLocking.hpp" |
50 #include "runtime/biasedLocking.hpp" |
51 #include "runtime/compilationPolicy.hpp" |
51 #include "runtime/compilationPolicy.hpp" |
52 #include "runtime/deoptimization.hpp" |
52 #include "runtime/deoptimization.hpp" |
|
53 #include "runtime/fieldDescriptor.hpp" |
|
54 #include "runtime/fieldDescriptor.inline.hpp" |
53 #include "runtime/frame.inline.hpp" |
55 #include "runtime/frame.inline.hpp" |
|
56 #include "runtime/jniHandles.inline.hpp" |
54 #include "runtime/handles.inline.hpp" |
57 #include "runtime/handles.inline.hpp" |
55 #include "runtime/interfaceSupport.inline.hpp" |
58 #include "runtime/interfaceSupport.inline.hpp" |
56 #include "runtime/safepointVerifiers.hpp" |
59 #include "runtime/safepointVerifiers.hpp" |
57 #include "runtime/sharedRuntime.hpp" |
60 #include "runtime/sharedRuntime.hpp" |
58 #include "runtime/signature.hpp" |
61 #include "runtime/signature.hpp" |
808 } |
811 } |
809 |
812 |
810 Deoptimization::DeoptAction Deoptimization::_unloaded_action |
813 Deoptimization::DeoptAction Deoptimization::_unloaded_action |
811 = Deoptimization::Action_reinterpret; |
814 = Deoptimization::Action_reinterpret; |
812 |
815 |
|
816 |
|
817 |
|
818 #if INCLUDE_JVMCI || INCLUDE_AOT |
|
819 template<typename CacheType> |
|
820 class BoxCacheBase : public CHeapObj<mtCompiler> { |
|
821 protected: |
|
822 static InstanceKlass* find_cache_klass(Symbol* klass_name, TRAPS) { |
|
823 ResourceMark rm; |
|
824 char* klass_name_str = klass_name->as_C_string(); |
|
825 Klass* k = SystemDictionary::find(klass_name, Handle(), Handle(), THREAD); |
|
826 guarantee(k != NULL, "%s must be loaded", klass_name_str); |
|
827 InstanceKlass* ik = InstanceKlass::cast(k); |
|
828 guarantee(ik->is_initialized(), "%s must be initialized", klass_name_str); |
|
829 CacheType::compute_offsets(ik); |
|
830 return ik; |
|
831 } |
|
832 }; |
|
833 |
|
834 template<typename PrimitiveType, typename CacheType, typename BoxType> class BoxCache : public BoxCacheBase<CacheType> { |
|
835 PrimitiveType _low; |
|
836 PrimitiveType _high; |
|
837 jobject _cache; |
|
838 protected: |
|
839 static BoxCache<PrimitiveType, CacheType, BoxType> *_singleton; |
|
840 BoxCache(Thread* thread) { |
|
841 InstanceKlass* ik = BoxCacheBase<CacheType>::find_cache_klass(CacheType::symbol(), thread); |
|
842 objArrayOop cache = CacheType::cache(ik); |
|
843 assert(cache->length() > 0, "Empty cache"); |
|
844 _low = BoxType::value(cache->obj_at(0)); |
|
845 _high = _low + cache->length() - 1; |
|
846 _cache = JNIHandles::make_global(Handle(thread, cache)); |
|
847 } |
|
848 ~BoxCache() { |
|
849 JNIHandles::destroy_global(_cache); |
|
850 } |
|
851 public: |
|
852 static BoxCache<PrimitiveType, CacheType, BoxType>* singleton(Thread* thread) { |
|
853 if (_singleton == NULL) { |
|
854 BoxCache<PrimitiveType, CacheType, BoxType>* s = new BoxCache<PrimitiveType, CacheType, BoxType>(thread); |
|
855 if (!Atomic::replace_if_null(s, &_singleton)) { |
|
856 delete s; |
|
857 } |
|
858 } |
|
859 return _singleton; |
|
860 } |
|
861 oop lookup(PrimitiveType value) { |
|
862 if (_low <= value && value <= _high) { |
|
863 int offset = value - _low; |
|
864 return objArrayOop(JNIHandles::resolve_non_null(_cache))->obj_at(offset); |
|
865 } |
|
866 return NULL; |
|
867 } |
|
868 }; |
|
869 |
|
870 typedef BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer> IntegerBoxCache; |
|
871 typedef BoxCache<jlong, java_lang_Long_LongCache, java_lang_Long> LongBoxCache; |
|
872 typedef BoxCache<jchar, java_lang_Character_CharacterCache, java_lang_Character> CharacterBoxCache; |
|
873 typedef BoxCache<jshort, java_lang_Short_ShortCache, java_lang_Short> ShortBoxCache; |
|
874 typedef BoxCache<jbyte, java_lang_Byte_ByteCache, java_lang_Byte> ByteBoxCache; |
|
875 |
|
876 template<> BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer>* BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer>::_singleton = NULL; |
|
877 template<> BoxCache<jlong, java_lang_Long_LongCache, java_lang_Long>* BoxCache<jlong, java_lang_Long_LongCache, java_lang_Long>::_singleton = NULL; |
|
878 template<> BoxCache<jchar, java_lang_Character_CharacterCache, java_lang_Character>* BoxCache<jchar, java_lang_Character_CharacterCache, java_lang_Character>::_singleton = NULL; |
|
879 template<> BoxCache<jshort, java_lang_Short_ShortCache, java_lang_Short>* BoxCache<jshort, java_lang_Short_ShortCache, java_lang_Short>::_singleton = NULL; |
|
880 template<> BoxCache<jbyte, java_lang_Byte_ByteCache, java_lang_Byte>* BoxCache<jbyte, java_lang_Byte_ByteCache, java_lang_Byte>::_singleton = NULL; |
|
881 |
|
882 class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> { |
|
883 jobject _true_cache; |
|
884 jobject _false_cache; |
|
885 protected: |
|
886 static BooleanBoxCache *_singleton; |
|
887 BooleanBoxCache(Thread *thread) { |
|
888 InstanceKlass* ik = find_cache_klass(java_lang_Boolean::symbol(), thread); |
|
889 _true_cache = JNIHandles::make_global(Handle(thread, java_lang_Boolean::get_TRUE(ik))); |
|
890 _false_cache = JNIHandles::make_global(Handle(thread, java_lang_Boolean::get_FALSE(ik))); |
|
891 } |
|
892 ~BooleanBoxCache() { |
|
893 JNIHandles::destroy_global(_true_cache); |
|
894 JNIHandles::destroy_global(_false_cache); |
|
895 } |
|
896 public: |
|
897 static BooleanBoxCache* singleton(Thread* thread) { |
|
898 if (_singleton == NULL) { |
|
899 BooleanBoxCache* s = new BooleanBoxCache(thread); |
|
900 if (!Atomic::replace_if_null(s, &_singleton)) { |
|
901 delete s; |
|
902 } |
|
903 } |
|
904 return _singleton; |
|
905 } |
|
906 oop lookup(jboolean value) { |
|
907 if (value != 0) { |
|
908 return JNIHandles::resolve_non_null(_true_cache); |
|
909 } |
|
910 return JNIHandles::resolve_non_null(_false_cache); |
|
911 } |
|
912 }; |
|
913 |
|
914 BooleanBoxCache* BooleanBoxCache::_singleton = NULL; |
|
915 |
|
916 oop Deoptimization::get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, TRAPS) { |
|
917 Klass* k = java_lang_Class::as_Klass(bv->klass()->as_ConstantOopReadValue()->value()()); |
|
918 BasicType box_type = SystemDictionary::box_klass_type(k); |
|
919 if (box_type != T_OBJECT) { |
|
920 StackValue* value = StackValue::create_stack_value(fr, reg_map, bv->field_at(0)); |
|
921 switch(box_type) { |
|
922 case T_INT: return IntegerBoxCache::singleton(THREAD)->lookup(value->get_int()); |
|
923 case T_LONG: { |
|
924 StackValue* low = StackValue::create_stack_value(fr, reg_map, bv->field_at(1)); |
|
925 jlong res = (jlong)low->get_int(); |
|
926 return LongBoxCache::singleton(THREAD)->lookup(res); |
|
927 } |
|
928 case T_CHAR: return CharacterBoxCache::singleton(THREAD)->lookup(value->get_int()); |
|
929 case T_SHORT: return ShortBoxCache::singleton(THREAD)->lookup(value->get_int()); |
|
930 case T_BYTE: return ByteBoxCache::singleton(THREAD)->lookup(value->get_int()); |
|
931 case T_BOOLEAN: return BooleanBoxCache::singleton(THREAD)->lookup(value->get_int()); |
|
932 default:; |
|
933 } |
|
934 } |
|
935 return NULL; |
|
936 } |
|
937 #endif // INCLUDE_JVMCI || INCLUDE_AOT |
|
938 |
813 #if COMPILER2_OR_JVMCI |
939 #if COMPILER2_OR_JVMCI |
814 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) { |
940 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, TRAPS) { |
815 Handle pending_exception(THREAD, thread->pending_exception()); |
941 Handle pending_exception(THREAD, thread->pending_exception()); |
816 const char* exception_file = thread->exception_file(); |
942 const char* exception_file = thread->exception_file(); |
817 int exception_line = thread->exception_line(); |
943 int exception_line = thread->exception_line(); |
818 thread->clear_pending_exception(); |
944 thread->clear_pending_exception(); |
819 |
945 |
825 |
951 |
826 Klass* k = java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()); |
952 Klass* k = java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()); |
827 oop obj = NULL; |
953 oop obj = NULL; |
828 |
954 |
829 if (k->is_instance_klass()) { |
955 if (k->is_instance_klass()) { |
|
956 #if INCLUDE_JVMCI || INCLUDE_AOT |
|
957 CompiledMethod* cm = fr->cb()->as_compiled_method_or_null(); |
|
958 if (cm->is_compiled_by_jvmci() && sv->is_auto_box()) { |
|
959 AutoBoxObjectValue* abv = (AutoBoxObjectValue*) sv; |
|
960 obj = get_cached_box(abv, fr, reg_map, THREAD); |
|
961 if (obj != NULL) { |
|
962 // Set the flag to indicate the box came from a cache, so that we can skip the field reassignment for it. |
|
963 abv->set_cached(true); |
|
964 } |
|
965 } |
|
966 #endif // INCLUDE_JVMCI || INCLUDE_AOT |
830 InstanceKlass* ik = InstanceKlass::cast(k); |
967 InstanceKlass* ik = InstanceKlass::cast(k); |
831 obj = ik->allocate_instance(THREAD); |
968 if (obj == NULL) { |
|
969 obj = ik->allocate_instance(THREAD); |
|
970 } |
832 } else if (k->is_typeArray_klass()) { |
971 } else if (k->is_typeArray_klass()) { |
833 TypeArrayKlass* ak = TypeArrayKlass::cast(k); |
972 TypeArrayKlass* ak = TypeArrayKlass::cast(k); |
834 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); |
973 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); |
835 int len = sv->field_size() / type2size[ak->element_type()]; |
974 int len = sv->field_size() / type2size[ak->element_type()]; |
836 obj = ak->allocate(len, THREAD); |
975 obj = ak->allocate(len, THREAD); |