JNI: Rewrite read barrier slow path.
Preserve all argument registers in the slow path to prepare
for moving arguments in registers for @FastNative. Move the
read barrier check earlier as it logically belongs to the
transition frame creation. For Baker read barriers, add a
mark bit check with fast return to the main path.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 172332525
Change-Id: I50bbc0bc9d54577281e7667aafebb4a53a539af1
diff --git a/compiler/utils/x86/jni_macro_assembler_x86.cc b/compiler/utils/x86/jni_macro_assembler_x86.cc
index f805556..2e7f23d 100644
--- a/compiler/utils/x86/jni_macro_assembler_x86.cc
+++ b/compiler/utils/x86/jni_macro_assembler_x86.cc
@@ -18,6 +18,7 @@
#include "base/casts.h"
#include "entrypoints/quick/quick_entrypoints.h"
+#include "lock_word.h"
#include "thread.h"
#include "utils/assembler.h"
@@ -590,27 +591,37 @@
__ jmp(X86JNIMacroLabel::Cast(label)->AsX86());
}
-void X86JNIMacroAssembler::TestGcMarking(JNIMacroLabel* label, JNIMacroUnaryCondition cond) {
- CHECK(label != nullptr);
-
- art::x86::Condition x86_cond;
+static Condition UnaryConditionToX86Condition(JNIMacroUnaryCondition cond) {
switch (cond) {
case JNIMacroUnaryCondition::kZero:
- x86_cond = art::x86::kZero;
- break;
+ return kZero;
case JNIMacroUnaryCondition::kNotZero:
- x86_cond = art::x86::kNotZero;
- break;
+ return kNotZero;
default:
LOG(FATAL) << "Not implemented condition: " << static_cast<int>(cond);
UNREACHABLE();
}
+}
+
+void X86JNIMacroAssembler::TestGcMarking(JNIMacroLabel* label, JNIMacroUnaryCondition cond) {
+ CHECK(label != nullptr);
// CMP self->tls32_.is_gc_marking, 0
// Jcc <Offset>
DCHECK_EQ(Thread::IsGcMarkingSize(), 4u);
__ fs()->cmpl(Address::Absolute(Thread::IsGcMarkingOffset<kX86PointerSize>()), Immediate(0));
- __ j(x86_cond, X86JNIMacroLabel::Cast(label)->AsX86());
+ __ j(UnaryConditionToX86Condition(cond), X86JNIMacroLabel::Cast(label)->AsX86());
+}
+
+void X86JNIMacroAssembler::TestMarkBit(ManagedRegister mref,
+ JNIMacroLabel* label,
+ JNIMacroUnaryCondition cond) {
+ DCHECK(kUseBakerReadBarrier);
+ Register ref = mref.AsX86().AsCpuRegister();
+ static_assert(LockWord::kMarkBitStateSize == 1u);
+ __ testl(Address(ref, mirror::Object::MonitorOffset().SizeValue()),
+ Immediate(LockWord::kMarkBitStateMaskShifted));
+ __ j(UnaryConditionToX86Condition(cond), X86JNIMacroLabel::Cast(label)->AsX86());
}
void X86JNIMacroAssembler::Bind(JNIMacroLabel* label) {