From ae7ff92c430aa12484ff8258ee4ed13421ac7934 Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Thu, 6 Oct 2016 14:59:19 -0700 Subject: jni: Add read barrier fast path to jni compiler Static method dispatch via JNI requires a read barrier for the ArtMethod::GetDeclaringClass() load before adding it to the JNI StackHandleScope. We used to call ReadBarrierJni unconditionally but add a branch to skip calling it if the GC is not currently in the marking phase. Test: ART_USE_READ_BARRIER=true make test-art-host test-art-target Bug: 30437917 Change-Id: I4f505ebde17c0a67209c7bb51b3f39e37a06373a --- compiler/utils/jni_macro_assembler.h | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'compiler/utils/jni_macro_assembler.h') diff --git a/compiler/utils/jni_macro_assembler.h b/compiler/utils/jni_macro_assembler.h index 0119ae9bfb..59a1a48e20 100644 --- a/compiler/utils/jni_macro_assembler.h +++ b/compiler/utils/jni_macro_assembler.h @@ -35,6 +35,12 @@ class ArenaAllocator; class DebugFrameOpCodeWriterForAssembler; class InstructionSetFeatures; class MemoryRegion; +class JNIMacroLabel; + +enum class JNIMacroUnaryCondition { + kZero, + kNotZero +}; template class JNIMacroAssembler : public DeletableArenaObject { @@ -193,6 +199,15 @@ class JNIMacroAssembler : public DeletableArenaObject { // and branch to a ExceptionSlowPath if it is. virtual void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust) = 0; + // Create a new label that can be used with Jump/Bind calls. + virtual std::unique_ptr CreateLabel() = 0; + // Emit an unconditional jump to the label. + virtual void Jump(JNIMacroLabel* label) = 0; + // Emit a conditional jump to the label by applying a unary condition test to the register. + virtual void Jump(JNIMacroLabel* label, JNIMacroUnaryCondition cond, ManagedRegister test) = 0; + // Code at this offset will serve as the target for the Jump call. + virtual void Bind(JNIMacroLabel* label) = 0; + virtual ~JNIMacroAssembler() {} /** @@ -205,6 +220,28 @@ class JNIMacroAssembler : public DeletableArenaObject { explicit JNIMacroAssembler() {} }; +// A "Label" class used with the JNIMacroAssembler +// allowing one to use branches (jumping from one place to another). +// +// This is just an interface, so every platform must provide +// its own implementation of it. +// +// It is only safe to use a label created +// via JNIMacroAssembler::CreateLabel with that same macro assembler. +class JNIMacroLabel { + public: + virtual ~JNIMacroLabel() = 0; + + const InstructionSet isa_; + protected: + explicit JNIMacroLabel(InstructionSet isa) : isa_(isa) {} +}; + +inline JNIMacroLabel::~JNIMacroLabel() { + // Compulsory definition for a pure virtual destructor + // to avoid linking errors. +} + template class JNIMacroAssemblerFwd : public JNIMacroAssembler { public: @@ -230,6 +267,30 @@ class JNIMacroAssemblerFwd : public JNIMacroAssembler { T asm_; }; +template +class JNIMacroLabelCommon : public JNIMacroLabel { + public: + static Self* Cast(JNIMacroLabel* label) { + CHECK(label != nullptr); + CHECK_EQ(kIsa, label->isa_); + + return reinterpret_cast(label); + } + + protected: + PlatformLabel* AsPlatformLabel() { + return &label_; + } + + JNIMacroLabelCommon() : JNIMacroLabel(kIsa) { + } + + virtual ~JNIMacroLabelCommon() OVERRIDE {} + + private: + PlatformLabel label_; +}; + } // namespace art #endif // ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_H_ -- cgit v1.2.3-59-g8ed1b