152 thread->inc_in_deopt_handler(); |
155 thread->inc_in_deopt_handler(); |
153 |
156 |
154 return fetch_unroll_info_helper(thread, exec_mode); |
157 return fetch_unroll_info_helper(thread, exec_mode); |
155 JRT_END |
158 JRT_END |
156 |
159 |
|
160 #if COMPILER2_OR_JVMCI |
|
161 static bool eliminate_allocations(JavaThread* thread, int exec_mode, CompiledMethod* compiled_method, |
|
162 frame& deoptee, RegisterMap& map, GrowableArray<compiledVFrame*>* chunk) { |
|
163 bool realloc_failures = false; |
|
164 assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); |
|
165 |
|
166 GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); |
|
167 |
|
168 // The flag return_oop() indicates call sites which return oop |
|
169 // in compiled code. Such sites include java method calls, |
|
170 // runtime calls (for example, used to allocate new objects/arrays |
|
171 // on slow code path) and any other calls generated in compiled code. |
|
172 // It is not guaranteed that we can get such information here only |
|
173 // by analyzing bytecode in deoptimized frames. This is why this flag |
|
174 // is set during method compilation (see Compile::Process_OopMap_Node()). |
|
175 // If the previous frame was popped or if we are dispatching an exception, |
|
176 // we don't have an oop result. |
|
177 bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution() && (exec_mode == Deoptimization::Unpack_deopt); |
|
178 Handle return_value; |
|
179 if (save_oop_result) { |
|
180 // Reallocation may trigger GC. If deoptimization happened on return from |
|
181 // call which returns oop we need to save it since it is not in oopmap. |
|
182 oop result = deoptee.saved_oop_result(&map); |
|
183 assert(oopDesc::is_oop_or_null(result), "must be oop"); |
|
184 return_value = Handle(thread, result); |
|
185 assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); |
|
186 if (TraceDeoptimization) { |
|
187 ttyLocker ttyl; |
|
188 tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread)); |
|
189 } |
|
190 } |
|
191 if (objects != NULL) { |
|
192 JRT_BLOCK |
|
193 realloc_failures = Deoptimization::realloc_objects(thread, &deoptee, &map, objects, THREAD); |
|
194 JRT_END |
|
195 bool skip_internal = (compiled_method != NULL) && !compiled_method->is_compiled_by_jvmci(); |
|
196 Deoptimization::reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal); |
|
197 #ifndef PRODUCT |
|
198 if (TraceDeoptimization) { |
|
199 ttyLocker ttyl; |
|
200 tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread)); |
|
201 Deoptimization::print_objects(objects, realloc_failures); |
|
202 } |
|
203 #endif |
|
204 } |
|
205 if (save_oop_result) { |
|
206 // Restore result. |
|
207 deoptee.set_saved_oop_result(&map, return_value()); |
|
208 } |
|
209 return realloc_failures; |
|
210 } |
|
211 |
|
212 static void eliminate_locks(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) { |
|
213 #ifndef PRODUCT |
|
214 bool first = true; |
|
215 #endif |
|
216 for (int i = 0; i < chunk->length(); i++) { |
|
217 compiledVFrame* cvf = chunk->at(i); |
|
218 assert (cvf->scope() != NULL,"expect only compiled java frames"); |
|
219 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
|
220 if (monitors->is_nonempty()) { |
|
221 Deoptimization::relock_objects(monitors, thread, realloc_failures); |
|
222 #ifndef PRODUCT |
|
223 if (PrintDeoptimizationDetails) { |
|
224 ttyLocker ttyl; |
|
225 for (int j = 0; j < monitors->length(); j++) { |
|
226 MonitorInfo* mi = monitors->at(j); |
|
227 if (mi->eliminated()) { |
|
228 if (first) { |
|
229 first = false; |
|
230 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, p2i(thread)); |
|
231 } |
|
232 if (mi->owner_is_scalar_replaced()) { |
|
233 Klass* k = java_lang_Class::as_Klass(mi->owner_klass()); |
|
234 tty->print_cr(" failed reallocation for klass %s", k->external_name()); |
|
235 } else { |
|
236 tty->print_cr(" object <" INTPTR_FORMAT "> locked", p2i(mi->owner())); |
|
237 } |
|
238 } |
|
239 } |
|
240 } |
|
241 #endif // !PRODUCT |
|
242 } |
|
243 } |
|
244 } |
|
245 #endif // COMPILER2_OR_JVMCI |
157 |
246 |
158 // This is factored, since it is both called from a JRT_LEAF (deoptimization) and a JRT_ENTRY (uncommon_trap) |
247 // This is factored, since it is both called from a JRT_LEAF (deoptimization) and a JRT_ENTRY (uncommon_trap) |
159 Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread, int exec_mode) { |
248 Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread, int exec_mode) { |
160 |
249 |
161 // Note: there is a safepoint safety issue here. No matter whether we enter |
250 // Note: there is a safepoint safety issue here. No matter whether we enter |
196 chunk->push(compiledVFrame::cast(vf)); |
285 chunk->push(compiledVFrame::cast(vf)); |
197 |
286 |
198 bool realloc_failures = false; |
287 bool realloc_failures = false; |
199 |
288 |
200 #if COMPILER2_OR_JVMCI |
289 #if COMPILER2_OR_JVMCI |
|
290 #if INCLUDE_JVMCI |
|
291 bool jvmci_enabled = true; |
|
292 #else |
|
293 bool jvmci_enabled = false; |
|
294 #endif |
|
295 |
201 // Reallocate the non-escaping objects and restore their fields. Then |
296 // Reallocate the non-escaping objects and restore their fields. Then |
202 // relock objects if synchronization on them was eliminated. |
297 // relock objects if synchronization on them was eliminated. |
203 #if !INCLUDE_JVMCI |
298 if (jvmci_enabled || (DoEscapeAnalysis && EliminateAllocations)) { |
204 if (DoEscapeAnalysis || EliminateNestedLocks) { |
299 realloc_failures = eliminate_allocations(thread, exec_mode, cm, deoptee, map, chunk); |
205 if (EliminateAllocations) { |
300 } |
206 #endif // INCLUDE_JVMCI |
301 #endif // COMPILER2_OR_JVMCI |
207 assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); |
302 |
208 GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); |
303 // Revoke biases, done with in java state. |
209 |
304 // No safepoints allowed after this |
210 // The flag return_oop() indicates call sites which return oop |
305 revoke_from_deopt_handler(thread, deoptee, &map); |
211 // in compiled code. Such sites include java method calls, |
306 |
212 // runtime calls (for example, used to allocate new objects/arrays |
307 // Ensure that no safepoint is taken after pointers have been stored |
213 // on slow code path) and any other calls generated in compiled code. |
308 // in fields of rematerialized objects. If a safepoint occurs from here on |
214 // It is not guaranteed that we can get such information here only |
309 // out the java state residing in the vframeArray will be missed. |
215 // by analyzing bytecode in deoptimized frames. This is why this flag |
310 // Locks may be rebaised in a safepoint. |
216 // is set during method compilation (see Compile::Process_OopMap_Node()). |
311 NoSafepointVerifier no_safepoint; |
217 // If the previous frame was popped or if we are dispatching an exception, |
312 |
218 // we don't have an oop result. |
313 #if COMPILER2_OR_JVMCI |
219 bool save_oop_result = chunk->at(0)->scope()->return_oop() && !thread->popframe_forcing_deopt_reexecution() && (exec_mode == Unpack_deopt); |
314 if (jvmci_enabled || ((DoEscapeAnalysis || EliminateNestedLocks) && EliminateLocks)) { |
220 Handle return_value; |
315 eliminate_locks(thread, chunk, realloc_failures); |
221 if (save_oop_result) { |
316 } |
222 // Reallocation may trigger GC. If deoptimization happened on return from |
|
223 // call which returns oop we need to save it since it is not in oopmap. |
|
224 oop result = deoptee.saved_oop_result(&map); |
|
225 assert(oopDesc::is_oop_or_null(result), "must be oop"); |
|
226 return_value = Handle(thread, result); |
|
227 assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); |
|
228 if (TraceDeoptimization) { |
|
229 ttyLocker ttyl; |
|
230 tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, p2i(result), p2i(thread)); |
|
231 } |
|
232 } |
|
233 if (objects != NULL) { |
|
234 JRT_BLOCK |
|
235 realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD); |
|
236 JRT_END |
|
237 bool skip_internal = (cm != NULL) && !cm->is_compiled_by_jvmci(); |
|
238 reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal); |
|
239 #ifndef PRODUCT |
|
240 if (TraceDeoptimization) { |
|
241 ttyLocker ttyl; |
|
242 tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, p2i(thread)); |
|
243 print_objects(objects, realloc_failures); |
|
244 } |
|
245 #endif |
|
246 } |
|
247 if (save_oop_result) { |
|
248 // Restore result. |
|
249 deoptee.set_saved_oop_result(&map, return_value()); |
|
250 } |
|
251 #if !INCLUDE_JVMCI |
|
252 } |
|
253 if (EliminateLocks) { |
|
254 #endif // INCLUDE_JVMCI |
|
255 #ifndef PRODUCT |
|
256 bool first = true; |
|
257 #endif |
|
258 for (int i = 0; i < chunk->length(); i++) { |
|
259 compiledVFrame* cvf = chunk->at(i); |
|
260 assert (cvf->scope() != NULL,"expect only compiled java frames"); |
|
261 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
|
262 if (monitors->is_nonempty()) { |
|
263 relock_objects(monitors, thread, realloc_failures); |
|
264 #ifndef PRODUCT |
|
265 if (PrintDeoptimizationDetails) { |
|
266 ttyLocker ttyl; |
|
267 for (int j = 0; j < monitors->length(); j++) { |
|
268 MonitorInfo* mi = monitors->at(j); |
|
269 if (mi->eliminated()) { |
|
270 if (first) { |
|
271 first = false; |
|
272 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, p2i(thread)); |
|
273 } |
|
274 if (mi->owner_is_scalar_replaced()) { |
|
275 Klass* k = java_lang_Class::as_Klass(mi->owner_klass()); |
|
276 tty->print_cr(" failed reallocation for klass %s", k->external_name()); |
|
277 } else { |
|
278 tty->print_cr(" object <" INTPTR_FORMAT "> locked", p2i(mi->owner())); |
|
279 } |
|
280 } |
|
281 } |
|
282 } |
|
283 #endif // !PRODUCT |
|
284 } |
|
285 } |
|
286 #if !INCLUDE_JVMCI |
|
287 } |
|
288 } |
|
289 #endif // INCLUDE_JVMCI |
|
290 #endif // COMPILER2_OR_JVMCI |
317 #endif // COMPILER2_OR_JVMCI |
291 |
318 |
292 ScopeDesc* trap_scope = chunk->at(0)->scope(); |
319 ScopeDesc* trap_scope = chunk->at(0)->scope(); |
293 Handle exceptionObject; |
320 Handle exceptionObject; |
294 if (trap_scope->rethrow_exception()) { |
321 if (trap_scope->rethrow_exception()) { |
775 |
797 |
776 return bt; |
798 return bt; |
777 JRT_END |
799 JRT_END |
778 |
800 |
779 class DeoptimizeMarkedTC : public ThreadClosure { |
801 class DeoptimizeMarkedTC : public ThreadClosure { |
780 bool _in_handshake; |
|
781 public: |
802 public: |
782 DeoptimizeMarkedTC(bool in_handshake) : _in_handshake(in_handshake) {} |
|
783 virtual void do_thread(Thread* thread) { |
803 virtual void do_thread(Thread* thread) { |
784 assert(thread->is_Java_thread(), "must be"); |
804 assert(thread->is_Java_thread(), "must be"); |
785 JavaThread* jt = (JavaThread*)thread; |
805 JavaThread* jt = (JavaThread*)thread; |
786 jt->deoptimize_marked_methods(_in_handshake); |
806 jt->deoptimize_marked_methods(); |
787 } |
807 } |
788 }; |
808 }; |
789 |
809 |
790 void Deoptimization::deoptimize_all_marked() { |
810 void Deoptimization::deoptimize_all_marked() { |
791 ResourceMark rm; |
811 ResourceMark rm; |
792 DeoptimizationMarker dm; |
812 DeoptimizationMarker dm; |
793 |
813 |
794 if (SafepointSynchronize::is_at_safepoint()) { |
814 if (SafepointSynchronize::is_at_safepoint()) { |
795 DeoptimizeMarkedTC deopt(false); |
815 DeoptimizeMarkedTC deopt; |
796 // Make the dependent methods not entrant |
816 // Make the dependent methods not entrant |
797 CodeCache::make_marked_nmethods_not_entrant(); |
817 CodeCache::make_marked_nmethods_not_entrant(); |
798 Threads::java_threads_do(&deopt); |
818 Threads::java_threads_do(&deopt); |
799 } else { |
819 } else { |
800 // Make the dependent methods not entrant |
820 // Make the dependent methods not entrant |
801 { |
821 { |
802 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
822 MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
803 CodeCache::make_marked_nmethods_not_entrant(); |
823 CodeCache::make_marked_nmethods_not_entrant(); |
804 } |
824 } |
805 DeoptimizeMarkedTC deopt(true); |
825 DeoptimizeMarkedTC deopt; |
806 Handshake::execute(&deopt); |
826 Handshake::execute(&deopt); |
807 } |
827 } |
808 } |
828 } |
809 |
829 |
810 Deoptimization::DeoptAction Deoptimization::_unloaded_action |
830 Deoptimization::DeoptAction Deoptimization::_unloaded_action |
811 = Deoptimization::Action_reinterpret; |
831 = Deoptimization::Action_reinterpret; |
812 |
832 |
|
833 |
|
834 |
|
835 #if INCLUDE_JVMCI || INCLUDE_AOT |
|
836 template<typename CacheType> |
|
837 class BoxCacheBase : public CHeapObj<mtCompiler> { |
|
838 protected: |
|
839 static InstanceKlass* find_cache_klass(Symbol* klass_name, TRAPS) { |
|
840 ResourceMark rm; |
|
841 char* klass_name_str = klass_name->as_C_string(); |
|
842 Klass* k = SystemDictionary::find(klass_name, Handle(), Handle(), THREAD); |
|
843 guarantee(k != NULL, "%s must be loaded", klass_name_str); |
|
844 InstanceKlass* ik = InstanceKlass::cast(k); |
|
845 guarantee(ik->is_initialized(), "%s must be initialized", klass_name_str); |
|
846 CacheType::compute_offsets(ik); |
|
847 return ik; |
|
848 } |
|
849 }; |
|
850 |
|
851 template<typename PrimitiveType, typename CacheType, typename BoxType> class BoxCache : public BoxCacheBase<CacheType> { |
|
852 PrimitiveType _low; |
|
853 PrimitiveType _high; |
|
854 jobject _cache; |
|
855 protected: |
|
856 static BoxCache<PrimitiveType, CacheType, BoxType> *_singleton; |
|
857 BoxCache(Thread* thread) { |
|
858 InstanceKlass* ik = BoxCacheBase<CacheType>::find_cache_klass(CacheType::symbol(), thread); |
|
859 objArrayOop cache = CacheType::cache(ik); |
|
860 assert(cache->length() > 0, "Empty cache"); |
|
861 _low = BoxType::value(cache->obj_at(0)); |
|
862 _high = _low + cache->length() - 1; |
|
863 _cache = JNIHandles::make_global(Handle(thread, cache)); |
|
864 } |
|
865 ~BoxCache() { |
|
866 JNIHandles::destroy_global(_cache); |
|
867 } |
|
868 public: |
|
869 static BoxCache<PrimitiveType, CacheType, BoxType>* singleton(Thread* thread) { |
|
870 if (_singleton == NULL) { |
|
871 BoxCache<PrimitiveType, CacheType, BoxType>* s = new BoxCache<PrimitiveType, CacheType, BoxType>(thread); |
|
872 if (!Atomic::replace_if_null(s, &_singleton)) { |
|
873 delete s; |
|
874 } |
|
875 } |
|
876 return _singleton; |
|
877 } |
|
878 oop lookup(PrimitiveType value) { |
|
879 if (_low <= value && value <= _high) { |
|
880 int offset = value - _low; |
|
881 return objArrayOop(JNIHandles::resolve_non_null(_cache))->obj_at(offset); |
|
882 } |
|
883 return NULL; |
|
884 } |
|
885 oop lookup_raw(intptr_t raw_value) { |
|
886 // Have to cast to avoid little/big-endian problems. |
|
887 if (sizeof(PrimitiveType) > sizeof(jint)) { |
|
888 jlong value = (jlong)raw_value; |
|
889 return lookup(value); |
|
890 } |
|
891 PrimitiveType value = (PrimitiveType)*((jint*)&raw_value); |
|
892 return lookup(value); |
|
893 } |
|
894 }; |
|
895 |
|
896 typedef BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer> IntegerBoxCache; |
|
897 typedef BoxCache<jlong, java_lang_Long_LongCache, java_lang_Long> LongBoxCache; |
|
898 typedef BoxCache<jchar, java_lang_Character_CharacterCache, java_lang_Character> CharacterBoxCache; |
|
899 typedef BoxCache<jshort, java_lang_Short_ShortCache, java_lang_Short> ShortBoxCache; |
|
900 typedef BoxCache<jbyte, java_lang_Byte_ByteCache, java_lang_Byte> ByteBoxCache; |
|
901 |
|
902 template<> BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer>* BoxCache<jint, java_lang_Integer_IntegerCache, java_lang_Integer>::_singleton = NULL; |
|
903 template<> BoxCache<jlong, java_lang_Long_LongCache, java_lang_Long>* BoxCache<jlong, java_lang_Long_LongCache, java_lang_Long>::_singleton = NULL; |
|
904 template<> BoxCache<jchar, java_lang_Character_CharacterCache, java_lang_Character>* BoxCache<jchar, java_lang_Character_CharacterCache, java_lang_Character>::_singleton = NULL; |
|
905 template<> BoxCache<jshort, java_lang_Short_ShortCache, java_lang_Short>* BoxCache<jshort, java_lang_Short_ShortCache, java_lang_Short>::_singleton = NULL; |
|
906 template<> BoxCache<jbyte, java_lang_Byte_ByteCache, java_lang_Byte>* BoxCache<jbyte, java_lang_Byte_ByteCache, java_lang_Byte>::_singleton = NULL; |
|
907 |
|
908 class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> { |
|
909 jobject _true_cache; |
|
910 jobject _false_cache; |
|
911 protected: |
|
912 static BooleanBoxCache *_singleton; |
|
913 BooleanBoxCache(Thread *thread) { |
|
914 InstanceKlass* ik = find_cache_klass(java_lang_Boolean::symbol(), thread); |
|
915 _true_cache = JNIHandles::make_global(Handle(thread, java_lang_Boolean::get_TRUE(ik))); |
|
916 _false_cache = JNIHandles::make_global(Handle(thread, java_lang_Boolean::get_FALSE(ik))); |
|
917 } |
|
918 ~BooleanBoxCache() { |
|
919 JNIHandles::destroy_global(_true_cache); |
|
920 JNIHandles::destroy_global(_false_cache); |
|
921 } |
|
922 public: |
|
923 static BooleanBoxCache* singleton(Thread* thread) { |
|
924 if (_singleton == NULL) { |
|
925 BooleanBoxCache* s = new BooleanBoxCache(thread); |
|
926 if (!Atomic::replace_if_null(s, &_singleton)) { |
|
927 delete s; |
|
928 } |
|
929 } |
|
930 return _singleton; |
|
931 } |
|
932 oop lookup_raw(intptr_t raw_value) { |
|
933 // Have to cast to avoid little/big-endian problems. |
|
934 jboolean value = (jboolean)*((jint*)&raw_value); |
|
935 return lookup(value); |
|
936 } |
|
937 oop lookup(jboolean value) { |
|
938 if (value != 0) { |
|
939 return JNIHandles::resolve_non_null(_true_cache); |
|
940 } |
|
941 return JNIHandles::resolve_non_null(_false_cache); |
|
942 } |
|
943 }; |
|
944 |
|
945 BooleanBoxCache* BooleanBoxCache::_singleton = NULL; |
|
946 |
|
947 oop Deoptimization::get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, TRAPS) { |
|
948 Klass* k = java_lang_Class::as_Klass(bv->klass()->as_ConstantOopReadValue()->value()()); |
|
949 BasicType box_type = SystemDictionary::box_klass_type(k); |
|
950 if (box_type != T_OBJECT) { |
|
951 StackValue* value = StackValue::create_stack_value(fr, reg_map, bv->field_at(box_type == T_LONG ? 1 : 0)); |
|
952 switch(box_type) { |
|
953 case T_INT: return IntegerBoxCache::singleton(THREAD)->lookup_raw(value->get_int()); |
|
954 case T_CHAR: return CharacterBoxCache::singleton(THREAD)->lookup_raw(value->get_int()); |
|
955 case T_SHORT: return ShortBoxCache::singleton(THREAD)->lookup_raw(value->get_int()); |
|
956 case T_BYTE: return ByteBoxCache::singleton(THREAD)->lookup_raw(value->get_int()); |
|
957 case T_BOOLEAN: return BooleanBoxCache::singleton(THREAD)->lookup_raw(value->get_int()); |
|
958 case T_LONG: return LongBoxCache::singleton(THREAD)->lookup_raw(value->get_int()); |
|
959 default:; |
|
960 } |
|
961 } |
|
962 return NULL; |
|
963 } |
|
964 #endif // INCLUDE_JVMCI || INCLUDE_AOT |
|
965 |
813 #if COMPILER2_OR_JVMCI |
966 #if COMPILER2_OR_JVMCI |
814 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) { |
967 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, TRAPS) { |
815 Handle pending_exception(THREAD, thread->pending_exception()); |
968 Handle pending_exception(THREAD, thread->pending_exception()); |
816 const char* exception_file = thread->exception_file(); |
969 const char* exception_file = thread->exception_file(); |
817 int exception_line = thread->exception_line(); |
970 int exception_line = thread->exception_line(); |
818 thread->clear_pending_exception(); |
971 thread->clear_pending_exception(); |
819 |
972 |
1121 MonitorInfo* mon_info = monitors->at(i); |
1292 MonitorInfo* mon_info = monitors->at(i); |
1122 if (mon_info->eliminated()) { |
1293 if (mon_info->eliminated()) { |
1123 assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed"); |
1294 assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed"); |
1124 if (!mon_info->owner_is_scalar_replaced()) { |
1295 if (!mon_info->owner_is_scalar_replaced()) { |
1125 Handle obj(thread, mon_info->owner()); |
1296 Handle obj(thread, mon_info->owner()); |
1126 markOop mark = obj->mark(); |
1297 markWord mark = obj->mark(); |
1127 if (UseBiasedLocking && mark->has_bias_pattern()) { |
1298 if (UseBiasedLocking && mark.has_bias_pattern()) { |
1128 // New allocated objects may have the mark set to anonymously biased. |
1299 // New allocated objects may have the mark set to anonymously biased. |
1129 // Also the deoptimized method may called methods with synchronization |
1300 // Also the deoptimized method may called methods with synchronization |
1130 // where the thread-local object is bias locked to the current thread. |
1301 // where the thread-local object is bias locked to the current thread. |
1131 assert(mark->is_biased_anonymously() || |
1302 assert(mark.is_biased_anonymously() || |
1132 mark->biased_locker() == thread, "should be locked to current thread"); |
1303 mark.biased_locker() == thread, "should be locked to current thread"); |
1133 // Reset mark word to unbiased prototype. |
1304 // Reset mark word to unbiased prototype. |
1134 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); |
1305 markWord unbiased_prototype = markWord::prototype().set_age(mark.age()); |
1135 obj->set_mark(unbiased_prototype); |
1306 obj->set_mark(unbiased_prototype); |
1136 } |
1307 } |
1137 BasicLock* lock = mon_info->lock(); |
1308 BasicLock* lock = mon_info->lock(); |
1138 ObjectSynchronizer::slow_enter(obj, lock, thread); |
1309 ObjectSynchronizer::enter(obj, lock, thread); |
1139 assert(mon_info->owner()->is_locked(), "object must be locked now"); |
1310 assert(mon_info->owner()->is_locked(), "object must be locked now"); |
1140 } |
1311 } |
1141 } |
1312 } |
1142 } |
1313 } |
1143 } |
1314 } |
1292 cvf = compiledVFrame::cast(cvf->sender()); |
1463 cvf = compiledVFrame::cast(cvf->sender()); |
1293 } |
1464 } |
1294 collect_monitors(cvf, objects_to_revoke); |
1465 collect_monitors(cvf, objects_to_revoke); |
1295 } |
1466 } |
1296 |
1467 |
1297 void Deoptimization::revoke_using_safepoint(JavaThread* thread, frame fr, RegisterMap* map) { |
1468 void Deoptimization::revoke_from_deopt_handler(JavaThread* thread, frame fr, RegisterMap* map) { |
1298 if (!UseBiasedLocking) { |
|
1299 return; |
|
1300 } |
|
1301 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); |
|
1302 get_monitors_from_stack(objects_to_revoke, thread, fr, map); |
|
1303 |
|
1304 if (SafepointSynchronize::is_at_safepoint()) { |
|
1305 BiasedLocking::revoke_at_safepoint(objects_to_revoke); |
|
1306 } else { |
|
1307 BiasedLocking::revoke(objects_to_revoke); |
|
1308 } |
|
1309 } |
|
1310 |
|
1311 void Deoptimization::revoke_using_handshake(JavaThread* thread, frame fr, RegisterMap* map) { |
|
1312 if (!UseBiasedLocking) { |
1469 if (!UseBiasedLocking) { |
1313 return; |
1470 return; |
1314 } |
1471 } |
1315 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); |
1472 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); |
1316 get_monitors_from_stack(objects_to_revoke, thread, fr, map); |
1473 get_monitors_from_stack(objects_to_revoke, thread, fr, map); |
1317 |
1474 |
1318 int len = objects_to_revoke->length(); |
1475 int len = objects_to_revoke->length(); |
1319 for (int i = 0; i < len; i++) { |
1476 for (int i = 0; i < len; i++) { |
1320 oop obj = (objects_to_revoke->at(i))(); |
1477 oop obj = (objects_to_revoke->at(i))(); |
1321 BiasedLocking::revoke_own_locks_in_handshake(objects_to_revoke->at(i), thread); |
1478 BiasedLocking::revoke_own_lock(objects_to_revoke->at(i), thread); |
1322 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
1479 assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now"); |
1323 } |
1480 } |
1324 } |
1481 } |
1325 |
1482 |
1326 |
1483 |
1327 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) { |
1484 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) { |
1349 // Patch the compiled method so that when execution returns to it we will |
1506 // Patch the compiled method so that when execution returns to it we will |
1350 // deopt the execution state and return to the interpreter. |
1507 // deopt the execution state and return to the interpreter. |
1351 fr.deoptimize(thread); |
1508 fr.deoptimize(thread); |
1352 } |
1509 } |
1353 |
1510 |
1354 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, bool in_handshake) { |
|
1355 deopt_thread(in_handshake, thread, fr, map, Reason_constraint); |
|
1356 } |
|
1357 |
|
1358 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) { |
1511 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) { |
1359 deopt_thread(false, thread, fr, map, reason); |
|
1360 } |
|
1361 |
|
1362 void Deoptimization::deopt_thread(bool in_handshake, JavaThread* thread, |
|
1363 frame fr, RegisterMap *map, DeoptReason reason) { |
|
1364 // Deoptimize only if the frame comes from compile code. |
1512 // Deoptimize only if the frame comes from compile code. |
1365 // Do not deoptimize the frame which is already patched |
1513 // Do not deoptimize the frame which is already patched |
1366 // during the execution of the loops below. |
1514 // during the execution of the loops below. |
1367 if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) { |
1515 if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) { |
1368 return; |
1516 return; |
1369 } |
1517 } |
1370 ResourceMark rm; |
1518 ResourceMark rm; |
1371 DeoptimizationMarker dm; |
1519 DeoptimizationMarker dm; |
1372 if (UseBiasedLocking) { |
|
1373 if (in_handshake) { |
|
1374 revoke_using_handshake(thread, fr, map); |
|
1375 } else { |
|
1376 revoke_using_safepoint(thread, fr, map); |
|
1377 } |
|
1378 } |
|
1379 deoptimize_single_frame(thread, fr, reason); |
1520 deoptimize_single_frame(thread, fr, reason); |
1380 |
|
1381 } |
1521 } |
1382 |
1522 |
1383 #if INCLUDE_JVMCI |
1523 #if INCLUDE_JVMCI |
1384 address Deoptimization::deoptimize_for_missing_exception_handler(CompiledMethod* cm) { |
1524 address Deoptimization::deoptimize_for_missing_exception_handler(CompiledMethod* cm) { |
1385 // there is no exception handler for this pc => deoptimize |
1525 // there is no exception handler for this pc => deoptimize |