< prev index next >
src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp
Print this page
rev 58823 : [mq]: aarch64-jdk-nmethod-barriers-3.patch
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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,16 +21,21 @@
* questions.
*
*/
#include "precompiled.hpp"
+#include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
+#include "gc/shared/barrierSetNMethod.hpp"
#include "gc/shared/collectedHeap.hpp"
+#include "interpreter/interp_masm.hpp"
#include "memory/universe.hpp"
#include "runtime/jniHandles.hpp"
+#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.hpp"
+
#define __ masm->
void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Address src, Register tmp1, Register tmp_thread) {
@@ -227,5 +232,69 @@
} else {
__ add(t1, t1, con_size_in_bytes);
}
__ str(t1, Address(rthread, in_bytes(JavaThread::allocated_bytes_offset())));
}
+
+void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
+ BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
+
+ if (bs_nm == NULL) {
+ return;
+ }
+
+ Label skip, guard;
+ Address thread_disarmed_addr(rthread, in_bytes(bs_nm->thread_disarmed_offset()));
+
+ __ ldrw(rscratch1, guard);
+
+ // Subsequent loads of oops must occur after load of guard value.
+ // BarrierSetNMethod::disarm sets guard with release semantics.
+ __ membar(__ LoadLoad);
+ __ ldrw(rscratch2, thread_disarmed_addr);
+ __ cmpw(rscratch1, rscratch2);
+ __ br(Assembler::EQ, skip);
+
+ __ mov(rscratch1, StubRoutines::aarch64::method_entry_barrier());
+ __ blr(rscratch1);
+ __ b(skip);
+
+ __ bind(guard);
+
+ __ emit_int32(0); // nmethod guard value. Skipped over in common case.
+
+ __ bind(skip);
+}
+
+void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
+ BarrierSetNMethod* bs = BarrierSet::barrier_set()->barrier_set_nmethod();
+ if (bs == NULL) {
+ return;
+ }
+
+ Label bad_call;
+ __ cbz(rmethod, bad_call);
+
+ // Pointer chase to the method holder to find out if the method is concurrently unloading.
+ Label method_live;
+ __ load_method_holder_cld(rscratch1, rmethod);
+
+ // Is it a strong CLD?
+ __ ldr(rscratch2, Address(rscratch1, ClassLoaderData::keep_alive_offset()));
+ __ cbnz(rscratch2, method_live);
+
+ // Is it a weak but alive CLD?
+ __ stp(r10, r11, Address(__ pre(sp, -2 * wordSize)));
+ __ ldr(r10, Address(rscratch1, ClassLoaderData::holder_offset()));
+
+ // Uses rscratch1 & rscratch2, so we must pass new temporaries.
+ __ resolve_weak_handle(r10, r11);
+ __ mov(rscratch1, r10);
+ __ ldp(r10, r11, Address(__ post(sp, 2 * wordSize)));
+ __ cbnz(rscratch1, method_live);
+
+ __ bind(bad_call);
+
+ __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+ __ bind(method_live);
+}
+
< prev index next >