< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp

Print this page

  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  *
 23  */
 24 
 25 

 26 #include "gc/shenandoah/shenandoahBarrierSetNMethod.hpp"
 27 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 28 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
 29 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 30 #include "gc/shenandoah/shenandoahLock.hpp"
 31 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
 32 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
 33 #include "memory/iterator.hpp"
 34 #include "memory/resourceArea.hpp"
 35 #include "runtime/threadWXSetters.inline.hpp"
 36 
 37 bool ShenandoahBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) {
 38   if (!is_armed(nm)) {
 39     // Some other thread got here first and healed the oops
 40     // and disarmed the nmethod. No need to continue.
 41     return true;
 42   }
 43 
 44   ShenandoahNMethodLock* lock = ShenandoahNMethod::lock_for_nmethod(nm);
 45   assert(lock != nullptr, "Must be");

 48   if (!is_armed(nm)) {
 49     // Some other thread managed to complete while we were
 50     // waiting for lock. No need to continue.
 51     return true;
 52   }
 53 
 54   MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current());)
 55 
 56   if (nm->is_unloading()) {
 57     // We don't need to take the lock when unlinking nmethods from
 58     // the Method, because it is only concurrently unlinked by
 59     // the entry barrier, which acquires the per nmethod lock.
 60     nm->unlink_from_method();
 61 
 62     // We can end up calling nmethods that are unloading
 63     // since we clear compiled ICs lazily. Returning false
 64     // will re-resovle the call and update the compiled IC.
 65     return false;
 66   }
 67 
 68   // Heal oops
 69   ShenandoahNMethod::heal_nmethod(nm);








 70 
 71   // CodeCache unloading support
 72   nm->mark_as_maybe_on_stack();
 73 
 74   // Disarm
 75   ShenandoahNMethod::disarm_nmethod(nm);
 76   return true;
 77 }


















  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  *
 23  */
 24 
 25 
 26 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
 27 #include "gc/shenandoah/shenandoahBarrierSetNMethod.hpp"
 28 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 29 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
 30 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 31 #include "gc/shenandoah/shenandoahLock.hpp"
 32 #include "gc/shenandoah/shenandoahNMethod.inline.hpp"
 33 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
 34 #include "memory/iterator.hpp"
 35 #include "memory/resourceArea.hpp"
 36 #include "runtime/threadWXSetters.inline.hpp"
 37 
 38 bool ShenandoahBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) {
 39   if (!is_armed(nm)) {
 40     // Some other thread got here first and healed the oops
 41     // and disarmed the nmethod. No need to continue.
 42     return true;
 43   }
 44 
 45   ShenandoahNMethodLock* lock = ShenandoahNMethod::lock_for_nmethod(nm);
 46   assert(lock != nullptr, "Must be");

 49   if (!is_armed(nm)) {
 50     // Some other thread managed to complete while we were
 51     // waiting for lock. No need to continue.
 52     return true;
 53   }
 54 
 55   MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current());)
 56 
 57   if (nm->is_unloading()) {
 58     // We don't need to take the lock when unlinking nmethods from
 59     // the Method, because it is only concurrently unlinked by
 60     // the entry barrier, which acquires the per nmethod lock.
 61     nm->unlink_from_method();
 62 
 63     // We can end up calling nmethods that are unloading
 64     // since we clear compiled ICs lazily. Returning false
 65     // will re-resovle the call and update the compiled IC.
 66     return false;
 67   }
 68 
 69   bool changed = false;
 70 
 71   // Handle oops and barriers.
 72   changed |= ShenandoahNMethod::handle_oops(nm);
 73   changed |= ShenandoahNMethod::handle_barriers(nm);
 74 
 75   // If any code changed, bulk invalidate the entire nmethod.
 76   if (changed) {
 77     ICache::invalidate_range(nm->code_begin(), nm->code_size());
 78   }
 79 
 80   // CodeCache unloading support
 81   nm->mark_as_maybe_on_stack();
 82 
 83   // Disarm
 84   ShenandoahNMethod::disarm_nmethod(nm);
 85   return true;
 86 }
 87 
 88 void ShenandoahBarrierSetNMethod::finalize_relocations(nmethod* nm) {
 89   RelocIterator iter(nm);
 90   while (iter.next()) {
 91     if (iter.type() == relocInfo::patchable_barrier_type) {
 92       patchable_barrier_Relocation* r = iter.patchable_barrier_reloc();
 93       if (!r->is_target_offset_resolved()) {
 94         address pc = r->addr();
 95         address target = ShenandoahBarrierSetAssembler::parse_jump_address(pc);
 96         r->set_target_offset(target - nm->code_begin());
 97       } else {
 98         // Already set. This is likely nmethod relocation, so just trust
 99         // the existing relocation data.
100       }
101     }
102   }
103 }
< prev index next >