jni: Add @CriticalNative optimization to speed up JNI transitions
Change-Id: I963059ac3a72dd8e6a867596c356d7062deb6da7
diff --git a/compiler/utils/arm/jni_macro_assembler_arm.cc b/compiler/utils/arm/jni_macro_assembler_arm.cc
index e0bfa12..cf7a4d1 100644
--- a/compiler/utils/arm/jni_macro_assembler_arm.cc
+++ b/compiler/utils/arm/jni_macro_assembler_arm.cc
@@ -367,11 +367,21 @@
CHECK(src.IsCoreRegister()) << src;
__ mov(dst.AsCoreRegister(), ShifterOperand(src.AsCoreRegister()));
} else if (dst.IsDRegister()) {
- CHECK(src.IsDRegister()) << src;
- __ vmovd(dst.AsDRegister(), src.AsDRegister());
+ if (src.IsDRegister()) {
+ __ vmovd(dst.AsDRegister(), src.AsDRegister());
+ } else {
+ // VMOV Dn, Rlo, Rhi (Dn = {Rlo, Rhi})
+ CHECK(src.IsRegisterPair()) << src;
+ __ vmovdrr(dst.AsDRegister(), src.AsRegisterPairLow(), src.AsRegisterPairHigh());
+ }
} else if (dst.IsSRegister()) {
- CHECK(src.IsSRegister()) << src;
- __ vmovs(dst.AsSRegister(), src.AsSRegister());
+ if (src.IsSRegister()) {
+ __ vmovs(dst.AsSRegister(), src.AsSRegister());
+ } else {
+ // VMOV Sn, Rn (Sn = Rn)
+ CHECK(src.IsCoreRegister()) << src;
+ __ vmovsr(dst.AsSRegister(), src.AsCoreRegister());
+ }
} else {
CHECK(dst.IsRegisterPair()) << dst;
CHECK(src.IsRegisterPair()) << src;
diff --git a/compiler/utils/assembler_thumb_test.cc b/compiler/utils/assembler_thumb_test.cc
index 367ed97..3b05173 100644
--- a/compiler/utils/assembler_thumb_test.cc
+++ b/compiler/utils/assembler_thumb_test.cc
@@ -1661,13 +1661,19 @@
TEST_F(ArmVIXLAssemblerTest, VixlJniHelpers) {
const bool is_static = true;
const bool is_synchronized = false;
+ const bool is_critical_native = false;
const char* shorty = "IIFII";
ArenaPool pool;
ArenaAllocator arena(&pool);
std::unique_ptr<JniCallingConvention> jni_conv(
- JniCallingConvention::Create(&arena, is_static, is_synchronized, shorty, kThumb2));
+ JniCallingConvention::Create(&arena,
+ is_static,
+ is_synchronized,
+ is_critical_native,
+ shorty,
+ kThumb2));
std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv(
ManagedRuntimeCallingConvention::Create(&arena, is_static, is_synchronized, shorty, kThumb2));
const int frame_size(jni_conv->FrameSize());