Fix handling of long argument spanning register/memory.
Comment in arm_lir.h says:
* If a 64-bit argument would span the register/memory argument
* boundary, it will instead be fully passed in the frame.
This change implements such logic for all platforms. We still need
to pass the low part in register as well because I haven't ported
the jni compilers (x86 and mips) to it.
Once the jni compilers are updated, we can remove the register
assignment.
Note that this greatly simplifies optimizing's register allocator
by not having to understand a long spanning register and memory.
Change-Id: I59706ca5d47269fc46e5489ac99bd6576e87e7f3
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 9db1646..4bec70a 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -304,14 +304,9 @@
}
uint64_t ReadSplitLongParam() const {
- DCHECK(IsSplitLongOrDouble());
- // Read low half from register.
- uint64_t low_half = *reinterpret_cast<uint32_t*>(GetParamAddress());
- // Read high half from the stack. As current stack_index_ indexes the argument, the high part
- // index should be (stack_index_ + 1).
- uint64_t high_half = *reinterpret_cast<uint32_t*>(stack_args_
- + (stack_index_ + 1) * kBytesStackArgLocation);
- return (low_half & 0xffffffffULL) | (high_half << 32);
+ // The splitted long is always available through the stack.
+ return *reinterpret_cast<uint64_t*>(stack_args_
+ + stack_index_ * kBytesStackArgLocation);
}
void VisitArguments() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {