< prev index next >
src/hotspot/share/runtime/deoptimization.cpp
Print this page
rev 56098 : imported patch 8226705-8221734-baseline
*** 777,790 ****
return bt;
JRT_END
! int Deoptimization::deoptimize_dependents() {
! Threads::deoptimized_wrt_marked_nmethods();
! return 0;
}
Deoptimization::DeoptAction Deoptimization::_unloaded_action
= Deoptimization::Action_reinterpret;
--- 777,815 ----
return bt;
JRT_END
+ class DeoptimizeMarkedTC : public ThreadClosure {
+ bool _in_handshake;
+ public:
+ DeoptimizeMarkedTC(bool in_handshake) : _in_handshake(in_handshake) {}
+ virtual void do_thread(Thread* thread) {
+ assert(thread->is_Java_thread(), "must be");
+ JavaThread* jt = (JavaThread*)thread;
+ jt->deoptimize_marked_methods(_in_handshake);
+ }
+ };
+
+ void Deoptimization::deoptimize_all_marked() {
+ ResourceMark rm;
+ DeoptimizationMarker dm;
! if (SafepointSynchronize::is_at_safepoint()) {
! DeoptimizeMarkedTC deopt(false);
! // Make the dependent methods not entrant
! CodeCache::make_marked_nmethods_not_entrant();
! Threads::java_threads_do(&deopt);
! } else {
! // Make the dependent methods not entrant
! {
! MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
! CodeCache::make_marked_nmethods_not_entrant();
! }
! DeoptimizeMarkedTC deopt(true);
! Handshake::execute(&deopt);
! }
}
Deoptimization::DeoptAction Deoptimization::_unloaded_action
= Deoptimization::Action_reinterpret;
*** 1395,1412 ****
objects_to_revoke->append(Handle(thread, mon_info->owner()));
}
}
}
!
! void Deoptimization::revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) {
! if (!UseBiasedLocking) {
! return;
! }
!
! GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
!
// Unfortunately we don't have a RegisterMap available in most of
// the places we want to call this routine so we need to walk the
// stack again to update the register map.
if (map == NULL || !map->update_map()) {
StackFrameStream sfs(thread, true);
--- 1420,1430 ----
objects_to_revoke->append(Handle(thread, mon_info->owner()));
}
}
}
! static void get_monitors_from_stack(GrowableArray<Handle>* objects_to_revoke, JavaThread* thread, frame fr, RegisterMap* map) {
// Unfortunately we don't have a RegisterMap available in most of
// the places we want to call this routine so we need to walk the
// stack again to update the register map.
if (map == NULL || !map->update_map()) {
StackFrameStream sfs(thread, true);
*** 1426,1443 ****
--- 1444,1484 ----
while (!cvf->is_top()) {
collect_monitors(cvf, objects_to_revoke);
cvf = compiledVFrame::cast(cvf->sender());
}
collect_monitors(cvf, objects_to_revoke);
+ }
+
+ void Deoptimization::revoke_using_safepoint(JavaThread* thread, frame fr, RegisterMap* map) {
+ if (!UseBiasedLocking) {
+ return;
+ }
+ GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
+ get_monitors_from_stack(objects_to_revoke, thread, fr, map);
if (SafepointSynchronize::is_at_safepoint()) {
BiasedLocking::revoke_at_safepoint(objects_to_revoke);
} else {
BiasedLocking::revoke(objects_to_revoke, thread);
}
}
+ void Deoptimization::revoke_using_handshake(JavaThread* thread, frame fr, RegisterMap* map) {
+ if (!UseBiasedLocking) {
+ return;
+ }
+ GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
+ get_monitors_from_stack(objects_to_revoke, thread, fr, map);
+
+ int len = objects_to_revoke->length();
+ for (int i = 0; i < len; i++) {
+ oop obj = (objects_to_revoke->at(i))();
+ BiasedLocking::revoke_own_locks_in_handshake(objects_to_revoke->at(i), thread);
+ assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
+ }
+ }
+
void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) {
assert(fr.can_be_deoptimized(), "checking frame type");
gather_statistics(reason, Action_none, Bytecodes::_illegal);
*** 1462,1486 ****
// Patch the compiled method so that when execution returns to it we will
// deopt the execution state and return to the interpreter.
fr.deoptimize(thread);
}
! void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) {
! deoptimize(thread, fr, map, Reason_constraint);
}
void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) {
// Deoptimize only if the frame comes from compile code.
// Do not deoptimize the frame which is already patched
// during the execution of the loops below.
if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) {
return;
}
ResourceMark rm;
DeoptimizationMarker dm;
if (UseBiasedLocking) {
! revoke_biases_of_monitors(thread, fr, map);
}
deoptimize_single_frame(thread, fr, reason);
}
--- 1503,1536 ----
// Patch the compiled method so that when execution returns to it we will
// deopt the execution state and return to the interpreter.
fr.deoptimize(thread);
}
! void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, bool in_handshake) {
! deopt_thread(in_handshake, thread, fr, map, Reason_constraint);
}
void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) {
+ deopt_thread(false, thread, fr, map, reason);
+ }
+
+ void Deoptimization::deopt_thread(bool in_handshake, JavaThread* thread,
+ frame fr, RegisterMap *map, DeoptReason reason) {
// Deoptimize only if the frame comes from compile code.
// Do not deoptimize the frame which is already patched
// during the execution of the loops below.
if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) {
return;
}
ResourceMark rm;
DeoptimizationMarker dm;
if (UseBiasedLocking) {
! if (in_handshake) {
! revoke_using_handshake(thread, fr, map);
! } else {
! revoke_using_safepoint(thread, fr, map);
! }
}
deoptimize_single_frame(thread, fr, reason);
}
< prev index next >