diff options
author | 2016-09-01 17:00:24 -0700 | |
---|---|---|
committer | 2016-09-09 10:48:56 -0700 | |
commit | 367f3dd32454858b8b25d87feb8f6599d3b4c9dd (patch) | |
tree | 9fe45c9f6785c31918f70ed2d12683f9c8d702af /compiler/jni/quick/calling_convention.h | |
parent | fa7b5c97db681e3d64d145807927cfafae78729b (diff) |
jni: Add @CriticalNative optimization to speed up JNI transitions
Change-Id: I963059ac3a72dd8e6a867596c356d7062deb6da7
Diffstat (limited to 'compiler/jni/quick/calling_convention.h')
-rw-r--r-- | compiler/jni/quick/calling_convention.h | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h index 995fa51d44..3d89146250 100644 --- a/compiler/jni/quick/calling_convention.h +++ b/compiler/jni/quick/calling_convention.h @@ -161,6 +161,12 @@ class CallingConvention : public DeletableArenaObject<kArenaAllocCallingConventi size_t NumArgs() const { return num_args_; } + // Implicit argument count: 1 for instance functions, 0 for static functions. + // (The implicit argument is only relevant to the shorty, i.e. + // the 0th arg is not in the shorty if it's implicit). + size_t NumImplicitArgs() const { + return IsStatic() ? 0 : 1; + } size_t NumLongOrDoubleArgs() const { return num_long_or_double_args_; } @@ -281,6 +287,7 @@ class JniCallingConvention : public CallingConvention { static std::unique_ptr<JniCallingConvention> Create(ArenaAllocator* arena, bool is_static, bool is_synchronized, + bool is_critical_native, const char* shorty, InstructionSet instruction_set); @@ -288,7 +295,8 @@ class JniCallingConvention : public CallingConvention { // always at the bottom of a frame, but this doesn't work for outgoing // native args). Includes alignment. virtual size_t FrameSize() = 0; - // Size of outgoing arguments, including alignment + // Size of outgoing arguments (stack portion), including alignment. + // -- Arguments that are passed via registers are excluded from this size. virtual size_t OutArgSize() = 0; // Number of references in stack indirect reference table size_t ReferenceCount() const; @@ -319,8 +327,11 @@ class JniCallingConvention : public CallingConvention { bool IsCurrentParamAFloatOrDouble(); bool IsCurrentParamADouble(); bool IsCurrentParamALong(); + bool IsCurrentParamALongOrDouble() { + return IsCurrentParamALong() || IsCurrentParamADouble(); + } bool IsCurrentParamJniEnv(); - size_t CurrentParamSize(); + size_t CurrentParamSize() const; virtual bool IsCurrentParamInRegister() = 0; virtual bool IsCurrentParamOnStack() = 0; virtual ManagedRegister CurrentParamRegister() = 0; @@ -359,18 +370,62 @@ class JniCallingConvention : public CallingConvention { kObjectOrClass = 1 }; + // TODO: remove this constructor once all are changed to the below one. JniCallingConvention(bool is_static, bool is_synchronized, const char* shorty, PointerSize frame_pointer_size) - : CallingConvention(is_static, is_synchronized, shorty, frame_pointer_size) {} + : CallingConvention(is_static, is_synchronized, shorty, frame_pointer_size), + is_critical_native_(false) {} + + JniCallingConvention(bool is_static, + bool is_synchronized, + bool is_critical_native, + const char* shorty, + PointerSize frame_pointer_size) + : CallingConvention(is_static, is_synchronized, shorty, frame_pointer_size), + is_critical_native_(is_critical_native) {} // Number of stack slots for outgoing arguments, above which the handle scope is // located virtual size_t NumberOfOutgoingStackArgs() = 0; protected: - size_t NumberOfExtraArgumentsForJni(); + size_t NumberOfExtraArgumentsForJni() const; + + // Does the transition have a StackHandleScope? + bool HasHandleScope() const; + // Does the transition have a local reference segment state? + bool HasLocalReferenceSegmentState() const; + // Has a JNIEnv* parameter implicitly? + bool HasJniEnv() const; + // Has a 'jclass' parameter implicitly? + bool HasSelfClass() const; + + // Are there extra JNI arguments (JNIEnv* and maybe jclass)? + bool HasExtraArgumentsForJni() const; + + // Returns the position of itr_args_, fixed up by removing the offset of extra JNI arguments. + unsigned int GetIteratorPositionWithinShorty() const; + + // Is the current argument (at the iterator) an extra argument for JNI? + bool IsCurrentArgExtraForJni() const; + + const bool is_critical_native_; + + private: + // Shorthand for switching on the switch value but only IF there are extra JNI arguments. + // + // Puts the case value into return_value. + // * (switch_value == kJniEnv) => case_jni_env + // * (switch_value == kObjectOrClass) => case_object_or_class + // + // Returns false otherwise (or if there are no extra JNI arguments). + bool SwitchExtraJniArguments(size_t switch_value, + bool case_jni_env, + bool case_object_or_class, + /* out parameters */ + bool* return_value) const; }; } // namespace art |