src/share/vm/runtime/biasedLocking.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8149383.02 Cdiff src/share/vm/runtime/biasedLocking.cpp

src/share/vm/runtime/biasedLocking.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 21,30 **** --- 21,32 ---- * questions. * */ #include "precompiled.hpp" + #include "logging/log.hpp" + #include "memory/resourceArea.hpp" #include "oops/klass.inline.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.inline.hpp" #include "runtime/basicLock.hpp"
*** 58,70 **** // currently loaded classes SystemDictionary::classes_do(enable_biased_locking); // Indicate that future instances should enable it as well _biased_locking_enabled = true; ! if (TraceBiasedLocking) { ! tty->print_cr("Biased locking enabled"); ! } } bool allow_nested_vm_operations() const { return false; } }; --- 60,70 ---- // currently loaded classes SystemDictionary::classes_do(enable_biased_locking); // Indicate that future instances should enable it as well _biased_locking_enabled = true; ! log_info(biasedlocking)("Biased locking enabled"); } bool allow_nested_vm_operations() const { return false; } };
*** 142,183 **** thread->set_cached_monitor_info(info); return info; } - static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) { markOop mark = obj->mark(); if (!mark->has_bias_pattern()) { ! if (TraceBiasedLocking) { ResourceMark rm; ! tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)", obj->klass()->external_name()); } return BiasedLocking::NOT_BIASED; } uint age = mark->age(); markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age); markOop unbiased_prototype = markOopDesc::prototype()->set_age(age); ! if (TraceBiasedLocking && (Verbose || !is_bulk)) { ResourceMark rm; ! tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT, ! p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); } JavaThread* biased_thread = mark->biased_locker(); if (biased_thread == NULL) { // Object is anonymously biased. We can get here if, for // example, we revoke the bias due to an identity hash code // being computed for an object. if (!allow_rebias) { obj->set_mark(unbiased_prototype); } ! if (TraceBiasedLocking && (Verbose || !is_bulk)) { ! tty->print_cr(" Revoked bias of anonymously-biased object"); } return BiasedLocking::BIAS_REVOKED; } // Handle case where the thread toward which the object was biased has exited --- 142,204 ---- thread->set_cached_monitor_info(info); return info; } static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) { markOop mark = obj->mark(); if (!mark->has_bias_pattern()) { ! if (log_is_enabled(Info, biasedlocking)) { ResourceMark rm; ! log_info(biasedlocking)(" (Skipping revocation of object of type %s " ! "because it's no longer biased)", obj->klass()->external_name()); } return BiasedLocking::NOT_BIASED; } uint age = mark->age(); markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age); markOop unbiased_prototype = markOopDesc::prototype()->set_age(age); ! // Log at "info" level if not bulk, else "trace" level ! if (!is_bulk) { ! ResourceMark rm; ! log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark " ! INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT ! " , allow rebias %d , requesting thread " INTPTR_FORMAT, ! p2i((void *)obj), ! (intptr_t) mark, ! obj->klass()->external_name(), ! (intptr_t) obj->klass()->prototype_header(), ! (allow_rebias ? 1 : 0), ! (intptr_t) requesting_thread); ! } else { ResourceMark rm; ! log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark " ! INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT ! " , allow rebias %d , requesting thread " INTPTR_FORMAT, ! p2i((void *)obj), ! (intptr_t) mark, ! obj->klass()->external_name(), ! (intptr_t) obj->klass()->prototype_header(), ! (allow_rebias ? 1 : 0), ! (intptr_t) requesting_thread); } JavaThread* biased_thread = mark->biased_locker(); if (biased_thread == NULL) { // Object is anonymously biased. We can get here if, for // example, we revoke the bias due to an identity hash code // being computed for an object. if (!allow_rebias) { obj->set_mark(unbiased_prototype); } ! if (!is_bulk) { ! log_info(biasedlocking)(" Revoked bias of anonymously-biased object"); ! } else { ! log_trace(biasedlocking)(" Revoked bias of anonymously-biased object"); } return BiasedLocking::BIAS_REVOKED; } // Handle case where the thread toward which the object was biased has exited
*** 196,207 **** if (allow_rebias) { obj->set_mark(biased_prototype); } else { obj->set_mark(unbiased_prototype); } ! if (TraceBiasedLocking && (Verbose || !is_bulk)) { ! tty->print_cr(" Revoked bias of object biased toward dead thread"); } return BiasedLocking::BIAS_REVOKED; } // Thread owning bias is alive. --- 217,231 ---- if (allow_rebias) { obj->set_mark(biased_prototype); } else { obj->set_mark(unbiased_prototype); } ! // Log at "info" level if not bulk, else "trace" level ! if (!is_bulk) { ! log_info(biasedlocking)(" Revoked bias of object biased toward dead thread"); ! } else { ! log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread"); } return BiasedLocking::BIAS_REVOKED; } // Thread owning bias is alive.
*** 212,253 **** GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread); BasicLock* highest_lock = NULL; for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); if (mon_info->owner() == obj) { ! if (TraceBiasedLocking && Verbose) { ! tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")", p2i((void *) mon_info->owner()), p2i((void *) obj)); - } // Assume recursive case and fix up highest lock later markOop mark = markOopDesc::encode((BasicLock*) NULL); highest_lock = mon_info->lock(); highest_lock->set_displaced_header(mark); } else { ! if (TraceBiasedLocking && Verbose) { ! tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")", p2i((void *) mon_info->owner()), p2i((void *) obj)); } } - } if (highest_lock != NULL) { // Fix up highest lock to contain displaced header and point // object at it highest_lock->set_displaced_header(unbiased_prototype); // Reset object header to point to displaced mark. // Must release storing the lock address for platforms without TSO // ordering (e.g. ppc). obj->release_set_mark(markOopDesc::encode(highest_lock)); assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit"); ! if (TraceBiasedLocking && (Verbose || !is_bulk)) { ! tty->print_cr(" Revoked bias of currently-locked object"); } } else { ! if (TraceBiasedLocking && (Verbose || !is_bulk)) { ! tty->print_cr(" Revoked bias of currently-unlocked object"); } if (allow_rebias) { obj->set_mark(biased_prototype); } else { // Store the unlocked value into the object's header. --- 236,279 ---- GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread); BasicLock* highest_lock = NULL; for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); if (mon_info->owner() == obj) { ! log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")", p2i((void *) mon_info->owner()), p2i((void *) obj)); // Assume recursive case and fix up highest lock later markOop mark = markOopDesc::encode((BasicLock*) NULL); highest_lock = mon_info->lock(); highest_lock->set_displaced_header(mark); } else { ! log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")", p2i((void *) mon_info->owner()), p2i((void *) obj)); } } if (highest_lock != NULL) { // Fix up highest lock to contain displaced header and point // object at it highest_lock->set_displaced_header(unbiased_prototype); // Reset object header to point to displaced mark. // Must release storing the lock address for platforms without TSO // ordering (e.g. ppc). obj->release_set_mark(markOopDesc::encode(highest_lock)); assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit"); ! // Log at "info" level if not bulk, else "trace" level ! if (!is_bulk) { ! log_info(biasedlocking)(" Revoked bias of currently-locked object"); ! } else { ! log_trace(biasedlocking)(" Revoked bias of currently-locked object"); } } else { ! // Log at "info" level if not bulk, else "trace" level ! if (!is_bulk) { ! log_info(biasedlocking)(" Revoked bias of currently-unlocked object"); ! } else { ! log_trace(biasedlocking)(" Revoked bias of currently-unlocked object"); } if (allow_rebias) { obj->set_mark(biased_prototype); } else { // Store the unlocked value into the object's header.
*** 324,339 **** bool bulk_rebias, bool attempt_rebias_of_object, JavaThread* requesting_thread) { assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); ! if (TraceBiasedLocking) { ! tty->print_cr("* Beginning bulk revocation (kind == %s) because of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", (bulk_rebias ? "rebias" : "revoke"), ! p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name()); ! } jlong cur_time = os::javaTimeMillis(); o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time); --- 350,365 ---- bool bulk_rebias, bool attempt_rebias_of_object, JavaThread* requesting_thread) { assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); ! log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", (bulk_rebias ? "rebias" : "revoke"), ! p2i((void *) o), ! (intptr_t) o->mark(), ! o->klass()->external_name()); jlong cur_time = os::javaTimeMillis(); o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
*** 375,387 **** // At this point we're done. All we have to do is potentially // adjust the header of the given object to revoke its bias. revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread); } else { ! if (TraceBiasedLocking) { ResourceMark rm; ! tty->print_cr("* Disabling biased locking for type %s", klass->external_name()); } // Disable biased locking for this data type. Not only will this // cause future instances to not be biased, but existing biased // instances will notice that this implicitly caused their biases --- 401,413 ---- // At this point we're done. All we have to do is potentially // adjust the header of the given object to revoke its bias. revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread); } else { ! if (log_is_enabled(Info, biasedlocking)) { ResourceMark rm; ! log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name()); } // Disable biased locking for this data type. Not only will this // cause future instances to not be biased, but existing biased // instances will notice that this implicitly caused their biases
*** 405,430 **** // Must force the bias of the passed object to be forcibly revoked // as well to ensure guarantees to callers revoke_bias(o, false, true, requesting_thread); } ! if (TraceBiasedLocking) { ! tty->print_cr("* Ending bulk revocation"); ! } BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED; if (attempt_rebias_of_object && o->mark()->has_bias_pattern() && klass->prototype_header()->has_bias_pattern()) { markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(), klass->prototype_header()->bias_epoch()); o->set_mark(new_mark); status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED; ! if (TraceBiasedLocking) { ! tty->print_cr(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread); ! } } assert(!o->mark()->has_bias_pattern() || (attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)), "bug in bulk bias revocation"); --- 431,452 ---- // Must force the bias of the passed object to be forcibly revoked // as well to ensure guarantees to callers revoke_bias(o, false, true, requesting_thread); } ! log_info(biasedlocking)("* Ending bulk revocation"); BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED; if (attempt_rebias_of_object && o->mark()->has_bias_pattern() && klass->prototype_header()->has_bias_pattern()) { markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(), klass->prototype_header()->bias_epoch()); o->set_mark(new_mark); status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED; ! log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread); } assert(!o->mark()->has_bias_pattern() || (attempt_rebias_of_object && (o->mark()->biased_locker() == requesting_thread)), "bug in bulk bias revocation");
*** 483,502 **** return false; } virtual void doit() { if (_obj != NULL) { ! if (TraceBiasedLocking) { ! tty->print_cr("Revoking bias with potentially per-thread safepoint:"); ! } _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread); clean_up_cached_monitor_info(); return; } else { ! if (TraceBiasedLocking) { ! tty->print_cr("Revoking bias with global safepoint:"); ! } BiasedLocking::revoke_at_safepoint(_objs); } } BiasedLocking::Condition status_code() const { --- 505,520 ---- return false; } virtual void doit() { if (_obj != NULL) { ! log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:"); _status_code = revoke_bias((*_obj)(), false, false, _requesting_thread); clean_up_cached_monitor_info(); return; } else { ! log_info(biasedlocking)("Revoking bias with global safepoint:"); BiasedLocking::revoke_at_safepoint(_objs); } } BiasedLocking::Condition status_code() const {
*** 606,618 **** // reach no safepoints in the revocation path. // Also check the epoch because even if threads match, another thread // can come in with a CAS to steal the bias of an object that has a // stale epoch. ResourceMark rm; ! if (TraceBiasedLocking) { ! tty->print_cr("Revoking bias by walking my own stack:"); ! } BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD); ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); assert(cond == BIAS_REVOKED, "why not?"); return cond; } else { --- 624,634 ---- // reach no safepoints in the revocation path. // Also check the epoch because even if threads match, another thread // can come in with a CAS to steal the bias of an object that has a // stale epoch. ResourceMark rm; ! log_info(biasedlocking)("Revoking bias by walking my own stack:"); BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD); ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); assert(cond == BIAS_REVOKED, "why not?"); return cond; } else {
src/share/vm/runtime/biasedLocking.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File