diff options
author | Igor Murashkin <iam@google.com> | 2016-10-06 14:59:19 -0700 |
---|---|---|
committer | Igor Murashkin <iam@google.com> | 2016-10-13 17:26:37 +0000 |
commit | ae7ff92c430aa12484ff8258ee4ed13421ac7934 (patch) | |
tree | 32774f5b3b0f96b921145a4af62dce182882fb7c /compiler/utils/jni_macro_assembler.h | |
parent | 6e5fa09510c7280168e040382d27dd8b55760d9a (diff) |
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
Diffstat (limited to 'compiler/utils/jni_macro_assembler.h')
-rw-r--r-- | compiler/utils/jni_macro_assembler.h | 61 |
1 files changed, 61 insertions, 0 deletions
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 <PointerSize kPointerSize> class JNIMacroAssembler : public DeletableArenaObject<kArenaAllocAssembler> { @@ -193,6 +199,15 @@ class JNIMacroAssembler : public DeletableArenaObject<kArenaAllocAssembler> { // 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<JNIMacroLabel> 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<kArenaAllocAssembler> { 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 <typename T, PointerSize kPointerSize> class JNIMacroAssemblerFwd : public JNIMacroAssembler<kPointerSize> { public: @@ -230,6 +267,30 @@ class JNIMacroAssemblerFwd : public JNIMacroAssembler<kPointerSize> { T asm_; }; +template <typename Self, typename PlatformLabel, InstructionSet kIsa> +class JNIMacroLabelCommon : public JNIMacroLabel { + public: + static Self* Cast(JNIMacroLabel* label) { + CHECK(label != nullptr); + CHECK_EQ(kIsa, label->isa_); + + return reinterpret_cast<Self*>(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_ |