< prev index next >

src/share/vm/runtime/biasedLocking.cpp

Print this page
rev 13259 : 8184181: Use oopDesc::cas_set_mark() instead of raw CAS when accessing oop header
Reviewed-by: dcubed, kbarret
   1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 562 };
 563 
 564 
 565 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
 566   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 567 
 568   // We can revoke the biases of anonymously-biased objects
 569   // efficiently enough that we should not cause these revocations to
 570   // update the heuristics because doing so may cause unwanted bulk
 571   // revocations (which are expensive) to occur.
 572   markOop mark = obj->mark();
 573   if (mark->is_biased_anonymously() && !attempt_rebias) {
 574     // We are probably trying to revoke the bias of this object due to
 575     // an identity hash code computation. Try to revoke the bias
 576     // without a safepoint. This is possible if we can successfully
 577     // compare-and-exchange an unbiased header into the mark word of
 578     // the object, meaning that no other thread has raced to acquire
 579     // the bias of the object.
 580     markOop biased_value       = mark;
 581     markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 582     markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);
 583     if (res_mark == biased_value) {
 584       return BIAS_REVOKED;
 585     }
 586   } else if (mark->has_bias_pattern()) {
 587     Klass* k = obj->klass();
 588     markOop prototype_header = k->prototype_header();
 589     if (!prototype_header->has_bias_pattern()) {
 590       // This object has a stale bias from before the bulk revocation
 591       // for this data type occurred. It's pointless to update the
 592       // heuristics at this point so simply update the header with a
 593       // CAS. If we fail this race, the object's bias has been revoked
 594       // by another thread so we simply return and let the caller deal
 595       // with it.
 596       markOop biased_value       = mark;
 597       markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, obj->mark_addr(), mark);
 598       assert(!(*(obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked");
 599       return BIAS_REVOKED;
 600     } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
 601       // The epoch of this biasing has expired indicating that the
 602       // object is effectively unbiased. Depending on whether we need
 603       // to rebias or revoke the bias of this object we can do it
 604       // efficiently enough with a CAS that we shouldn't update the
 605       // heuristics. This is normally done in the assembly code but we
 606       // can reach this point due to various points in the runtime
 607       // needing to revoke biases.
 608       if (attempt_rebias) {
 609         assert(THREAD->is_Java_thread(), "");
 610         markOop biased_value       = mark;
 611         markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
 612         markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, obj->mark_addr(), mark);
 613         if (res_mark == biased_value) {
 614           return BIAS_REVOKED_AND_REBIASED;
 615         }
 616       } else {
 617         markOop biased_value       = mark;
 618         markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 619         markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);
 620         if (res_mark == biased_value) {
 621           return BIAS_REVOKED;
 622         }
 623       }
 624     }
 625   }
 626 
 627   HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
 628   if (heuristics == HR_NOT_BIASED) {
 629     return NOT_BIASED;
 630   } else if (heuristics == HR_SINGLE_REVOKE) {
 631     Klass *k = obj->klass();
 632     markOop prototype_header = k->prototype_header();
 633     if (mark->biased_locker() == THREAD &&
 634         prototype_header->bias_epoch() == mark->bias_epoch()) {
 635       // A thread is trying to revoke the bias of an object biased
 636       // toward it, again likely due to an identity hash code
 637       // computation. We can again avoid a safepoint in this case
 638       // since we are only going to walk our own stack. There are no
 639       // races with revocations occurring in other threads because we


   1 /*
   2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 562 };
 563 
 564 
 565 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
 566   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 567 
 568   // We can revoke the biases of anonymously-biased objects
 569   // efficiently enough that we should not cause these revocations to
 570   // update the heuristics because doing so may cause unwanted bulk
 571   // revocations (which are expensive) to occur.
 572   markOop mark = obj->mark();
 573   if (mark->is_biased_anonymously() && !attempt_rebias) {
 574     // We are probably trying to revoke the bias of this object due to
 575     // an identity hash code computation. Try to revoke the bias
 576     // without a safepoint. This is possible if we can successfully
 577     // compare-and-exchange an unbiased header into the mark word of
 578     // the object, meaning that no other thread has raced to acquire
 579     // the bias of the object.
 580     markOop biased_value       = mark;
 581     markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 582     markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 583     if (res_mark == biased_value) {
 584       return BIAS_REVOKED;
 585     }
 586   } else if (mark->has_bias_pattern()) {
 587     Klass* k = obj->klass();
 588     markOop prototype_header = k->prototype_header();
 589     if (!prototype_header->has_bias_pattern()) {
 590       // This object has a stale bias from before the bulk revocation
 591       // for this data type occurred. It's pointless to update the
 592       // heuristics at this point so simply update the header with a
 593       // CAS. If we fail this race, the object's bias has been revoked
 594       // by another thread so we simply return and let the caller deal
 595       // with it.
 596       markOop biased_value       = mark;
 597       markOop res_mark = obj->cas_set_mark(prototype_header, mark);
 598       assert(!(*(obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked");
 599       return BIAS_REVOKED;
 600     } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
 601       // The epoch of this biasing has expired indicating that the
 602       // object is effectively unbiased. Depending on whether we need
 603       // to rebias or revoke the bias of this object we can do it
 604       // efficiently enough with a CAS that we shouldn't update the
 605       // heuristics. This is normally done in the assembly code but we
 606       // can reach this point due to various points in the runtime
 607       // needing to revoke biases.
 608       if (attempt_rebias) {
 609         assert(THREAD->is_Java_thread(), "");
 610         markOop biased_value       = mark;
 611         markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
 612         markOop res_mark = obj->cas_set_mark(rebiased_prototype, mark);
 613         if (res_mark == biased_value) {
 614           return BIAS_REVOKED_AND_REBIASED;
 615         }
 616       } else {
 617         markOop biased_value       = mark;
 618         markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
 619         markOop res_mark = obj->cas_set_mark(unbiased_prototype, mark);
 620         if (res_mark == biased_value) {
 621           return BIAS_REVOKED;
 622         }
 623       }
 624     }
 625   }
 626 
 627   HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
 628   if (heuristics == HR_NOT_BIASED) {
 629     return NOT_BIASED;
 630   } else if (heuristics == HR_SINGLE_REVOKE) {
 631     Klass *k = obj->klass();
 632     markOop prototype_header = k->prototype_header();
 633     if (mark->biased_locker() == THREAD &&
 634         prototype_header->bias_epoch() == mark->bias_epoch()) {
 635       // A thread is trying to revoke the bias of an object biased
 636       // toward it, again likely due to an identity hash code
 637       // computation. We can again avoid a safepoint in this case
 638       // since we are only going to walk our own stack. There are no
 639       // races with revocations occurring in other threads because we


< prev index next >