summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-04-21 19:28:24 -0700
committerAndreas Gampe <agampe@google.com>2014-04-25 16:13:27 -0700
commit5c1e4352614d61fed6868567e58b96682828cb4d (patch)
treec723c7883f80083b885c590a7fc514684667c1a3 /runtime
parent7f40b111755e300ddddd6839425337fe3af8d4e7 (diff)
downloadart-5c1e4352614d61fed6868567e58b96682828cb4d.zip
art-5c1e4352614d61fed6868567e58b96682828cb4d.tar.gz
art-5c1e4352614d61fed6868567e58b96682828cb4d.tar.bz2
Add "arch_test" gtest for assembly stub constants, add some ARM64 assembly code
Add a test that (1) checks all callee-save method frame sizes for all architectures, (2) checks thread offsets for the runtime architecture and (3) checks callee-save method offsets for the runtime architecture. The "asm_support_XXX.h" files now only contain definitions that are common between all architectures. Architecture-specific definitions (i.e., special registers names) have been pushed into the corresponding .S file. This change was required to be able to undefine definitions in the test, so that multiple tests can be written in one file. Test (1) above is in a sense two-stage. The arch_test gtest compares constants (if it finds them) against the frame size as reported by the ArtMethods created by the Runtime. This works for all architectures as we can provide the instruction-set to CreateCalleeSaveMethod. The second stage of the "test" are preprocessor tests with "#error" in the case that the constants are not the expected value. Optimally I'd like to change that to an actual runtime test exercising the assembly code, which would also allow to check whether the right registers are stored. Also added missing assembly code for ARM64 for the callee-save macros. Also fix X86_64 compilation for Clang 3.5. Change-Id: I018e6433dffd3d31ba3bfcd75661653f4c7b6552
Diffstat (limited to 'runtime')
-rw-r--r--runtime/arch/arch_test.cc498
-rw-r--r--runtime/arch/arm/asm_support_arm.S7
-rw-r--r--runtime/arch/arm/asm_support_arm.h8
-rw-r--r--runtime/arch/arm/quick_entrypoints_arm.S15
-rw-r--r--runtime/arch/arm64/asm_support_arm64.S13
-rw-r--r--runtime/arch/arm64/asm_support_arm64.h13
-rw-r--r--runtime/arch/arm64/quick_entrypoints_arm64.S77
-rw-r--r--runtime/arch/mips/asm_support_mips.S8
-rw-r--r--runtime/arch/mips/asm_support_mips.h8
-rw-r--r--runtime/arch/mips/quick_entrypoints_mips.S18
-rw-r--r--runtime/arch/x86/asm_support_x86.h4
-rw-r--r--runtime/arch/x86/quick_entrypoints_x86.S17
-rw-r--r--runtime/arch/x86_64/asm_support_x86_64.S6
-rw-r--r--runtime/arch/x86_64/asm_support_x86_64.h4
-rw-r--r--runtime/arch/x86_64/quick_entrypoints_x86_64.S18
15 files changed, 691 insertions, 23 deletions
diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc
new file mode 100644
index 0000000..47c6d28
--- /dev/null
+++ b/runtime/arch/arch_test.cc
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#include "common_runtime_test.h"
+#include "mirror/art_method.h"
+
+namespace art {
+
+class ArchTest : public CommonRuntimeTest {
+ protected:
+ static void CheckFrameSize(InstructionSet isa, Runtime::CalleeSaveType type, uint32_t save_size)
+ NO_THREAD_SAFETY_ANALYSIS {
+ Runtime* r = Runtime::Current();
+
+ Thread* t = Thread::Current();
+ t->TransitionFromSuspendedToRunnable(); // So we can create callee-save methods.
+
+ mirror::ArtMethod* save_method = r->CreateCalleeSaveMethod(isa, type);
+ EXPECT_EQ(save_method->GetFrameSizeInBytes(), save_size) << "Expected and real size differs for "
+ << type << " core spills=" << std::hex << save_method->GetCoreSpillMask() << " fp spills="
+ << save_method->GetFpSpillMask() << std::dec;
+
+ t->TransitionFromRunnableToSuspended(ThreadState::kNative); // So we can shut down.
+ }
+};
+
+
+TEST_F(ArchTest, ARM) {
+#include "arch/arm/asm_support_arm.h"
+#undef ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_H_
+
+
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kArm, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for SaveAll";
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kArm, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsOnly";
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kArm, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsAndArgs";
+#endif
+
+
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+
+TEST_F(ArchTest, ARM64) {
+#include "arch/arm64/asm_support_arm64.h"
+#undef ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_
+
+
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kArm64, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for SaveAll";
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsOnly";
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsAndArgs";
+#endif
+
+
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+
+TEST_F(ArchTest, MIPS) {
+#include "arch/mips/asm_support_mips.h"
+#undef ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_
+
+
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kMips, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for SaveAll";
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kMips, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsOnly";
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kMips, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsAndArgs";
+#endif
+
+
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+
+TEST_F(ArchTest, X86) {
+#include "arch/x86/asm_support_x86.h"
+#undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
+
+
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kX86, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for SaveAll";
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kX86, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsOnly";
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kX86, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsAndArgs";
+#endif
+
+
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+
+TEST_F(ArchTest, X86_64) {
+#include "arch/x86_64/asm_support_x86_64.h"
+#undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
+
+
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kX86_64, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for SaveAll";
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsOnly";
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+ CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE);
+#else
+ LOG(WARNING) << "No frame size for RefsAndArgs";
+#endif
+
+
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+
+TEST_F(ArchTest, ThreadOffsets) {
+#if defined(__arm__)
+#include "arch/arm/asm_support_arm.h"
+#undef ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_H_
+#elif defined(__aarch64__)
+#include "arch/arm64/asm_support_arm64.h"
+#undef ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_
+#elif defined(__mips__)
+#include "arch/mips/asm_support_mips.h"
+#undef ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_
+#elif defined(__i386__)
+#include "arch/x86/asm_support_x86.h"
+#undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
+#elif defined(__x86_64__)
+#include "arch/x86_64/asm_support_x86_64.h"
+#undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
+#else
+ // This happens for the host test.
+#ifdef __LP64__
+#include "arch/x86_64/asm_support_x86_64.h"
+#undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
+#else
+#include "arch/x86/asm_support_x86.h"
+#undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
+#endif
+#endif
+
+ // Ugly hack, change when possible.
+#ifdef __LP64__
+#define POINTER_SIZE 8
+#else
+#define POINTER_SIZE 4
+#endif
+
+#if defined(THREAD_SELF_OFFSET)
+ ThreadOffset<POINTER_SIZE> self_offset = Thread::SelfOffset<POINTER_SIZE>();
+ EXPECT_EQ(self_offset.Int32Value(), THREAD_SELF_OFFSET);
+#else
+ LOG(INFO) << "No Thread Self Offset found.";
+#endif
+
+#if defined(THREAD_CARD_TABLE_OFFSET)
+ ThreadOffset<POINTER_SIZE> card_offset = Thread::CardTableOffset<POINTER_SIZE>();
+ EXPECT_EQ(card_offset.Int32Value(), THREAD_CARD_TABLE_OFFSET);
+#else
+ LOG(INFO) << "No Thread Card Table Offset found.";
+#endif
+
+#if defined(THREAD_EXCEPTION_OFFSET)
+ ThreadOffset<POINTER_SIZE> exc_offset = Thread::ExceptionOffset<POINTER_SIZE>();
+ EXPECT_EQ(exc_offset.Int32Value(), THREAD_EXCEPTION_OFFSET);
+#else
+ LOG(INFO) << "No Thread Exception Offset found.";
+#endif
+
+#if defined(THREAD_ID_OFFSET)
+ ThreadOffset<POINTER_SIZE> id_offset = Thread::ThinLockIdOffset<POINTER_SIZE>();
+ EXPECT_EQ(id_offset.Int32Value(), THREAD_ID_OFFSET);
+#else
+ LOG(INFO) << "No Thread ID Offset found.";
+#endif
+
+
+ // Undefine everything for the next test
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+
+TEST_F(ArchTest, CalleeSaveMethodOffsets) {
+#if defined(__arm__)
+#include "arch/arm/asm_support_arm.h"
+#undef ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_H_
+#elif defined(__aarch64__)
+#include "arch/arm64/asm_support_arm64.h"
+#undef ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_
+#elif defined(__mips__)
+#include "arch/mips/asm_support_mips.h"
+#undef ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_
+#elif defined(__i386__)
+#include "arch/x86/asm_support_x86.h"
+#undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
+#elif defined(__x86_64__)
+#include "arch/x86_64/asm_support_x86_64.h"
+#undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
+#else
+ // This happens for the host test.
+#ifdef __LP64__
+#include "arch/x86_64/asm_support_x86_64.h"
+#undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
+#else
+#include "arch/x86/asm_support_x86.h"
+#undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
+#endif
+#endif
+
+
+#if defined(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET)
+ EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kSaveAll),
+ static_cast<size_t>(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET));
+#else
+ LOG(INFO) << "No Runtime Save-all Offset found.";
+#endif
+
+#if defined(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET)
+ EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kRefsOnly),
+ static_cast<size_t>(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET));
+#else
+ LOG(INFO) << "No Runtime Refs-only Offset found.";
+#endif
+
+#if defined(RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET)
+ EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kRefsAndArgs),
+ static_cast<size_t>(RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET));
+#else
+ LOG(INFO) << "No Runtime Refs-and-Args Offset found.";
+#endif
+
+
+ // Undefine everything for the next test
+#ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET
+#endif
+#ifdef THREAD_SELF_OFFSET
+#undef THREAD_SELF_OFFSET
+#endif
+#ifdef THREAD_CARD_TABLE_OFFSET
+#undef THREAD_CARD_TABLE_OFFSET
+#endif
+#ifdef THREAD_EXCEPTION_OFFSET
+#undef THREAD_EXCEPTION_OFFSET
+#endif
+#ifdef THREAD_ID_OFFSET
+#undef THREAD_ID_OFFSET
+#endif
+#ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE
+#endif
+#ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE
+#endif
+}
+
+} // namespace art
diff --git a/runtime/arch/arm/asm_support_arm.S b/runtime/arch/arm/asm_support_arm.S
index fb85feb..594252a 100644
--- a/runtime/arch/arm/asm_support_arm.S
+++ b/runtime/arch/arm/asm_support_arm.S
@@ -19,6 +19,13 @@
#include "asm_support_arm.h"
+// Define special registers.
+
+// Register holding suspend check count down.
+#define rSUSPEND r4
+// Register holding Thread::Current().
+#define rSELF r9
+
.cfi_sections .debug_frame
.syntax unified
.arch armv7-a
diff --git a/runtime/arch/arm/asm_support_arm.h b/runtime/arch/arm/asm_support_arm.h
index 4b64076..a73d522 100644
--- a/runtime/arch/arm/asm_support_arm.h
+++ b/runtime/arch/arm/asm_support_arm.h
@@ -19,10 +19,6 @@
#include "asm_support.h"
-// Register holding suspend check count down.
-#define rSUSPEND r4
-// Register holding Thread::Current().
-#define rSELF r9
// Offset of field Thread::tls32_.state_and_flags verified in InitCpu
#define THREAD_FLAGS_OFFSET 0
// Offset of field Thread::tls32_.thin_lock_thread_id verified in InitCpu
@@ -32,4 +28,8 @@
// Offset of field Thread::tlsPtr_.exception verified in InitCpu
#define THREAD_EXCEPTION_OFFSET 116
+#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 176
+#define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 32
+#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 48
+
#endif // ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_H_
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 7cc8da8..bc80644 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -46,6 +46,11 @@
sub sp, #12 @ 3 words of space, bottom word will hold Method*
.pad #12
.cfi_adjust_cfa_offset 12
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 36 + 128 + 12)
+#error "SAVE_ALL_CALLEE_SAVE_FRAME(ARM) size not as expected."
+#endif
.endm
/*
@@ -66,6 +71,11 @@
sub sp, #4 @ bottom word will hold Method*
.pad #4
.cfi_adjust_cfa_offset 4
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 28 + 4)
+#error "REFS_ONLY_CALLEE_SAVE_FRAME(ARM) size not as expected."
+#endif
.endm
.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
@@ -114,6 +124,11 @@
sub sp, #8 @ 2 words of space, bottom word will hold Method*
.pad #8
.cfi_adjust_cfa_offset 8
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 40 + 8)
+#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(ARM64) size not as expected."
+#endif
.endm
.macro RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME
diff --git a/runtime/arch/arm64/asm_support_arm64.S b/runtime/arch/arm64/asm_support_arm64.S
index 634f777..9614c29 100644
--- a/runtime/arch/arm64/asm_support_arm64.S
+++ b/runtime/arch/arm64/asm_support_arm64.S
@@ -19,6 +19,19 @@
#include "asm_support_arm64.h"
+// Define special registers.
+
+// Register holding Thread::Current().
+#define xSELF x18
+// Frame Pointer
+#define xFP x29
+// Link Register
+#define xLR x30
+// Define the intraprocedural linkage temporary registers.
+#define xIP0 x16
+#define xIP1 x17
+
+
.cfi_sections .debug_frame
.macro ENTRY name
diff --git a/runtime/arch/arm64/asm_support_arm64.h b/runtime/arch/arm64/asm_support_arm64.h
index a7e68ed..b18e415 100644
--- a/runtime/arch/arm64/asm_support_arm64.h
+++ b/runtime/arch/arm64/asm_support_arm64.h
@@ -28,15 +28,6 @@
// Offset of field Runtime::callee_save_methods_[kRefsAndArgs]
#define RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 16
-// Register holding Thread::Current().
-#define xSELF x18
-// Frame Pointer
-#define xFP x29
-// Link Register
-#define xLR x30
-// Define the intraprocedural linkage temporary registers.
-#define xIP0 x16
-#define xIP1 x17
// Offset of field Thread::suspend_count_ verified in InitCpu
#define THREAD_FLAGS_OFFSET 0
// Offset of field Thread::card_table_ verified in InitCpu
@@ -46,4 +37,8 @@
// Offset of field Thread::thin_lock_thread_id_ verified in InitCpu
#define THREAD_ID_OFFSET 12
+#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 368
+#define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 176
+#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 304
+
#endif // ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 1350198..71f5bf7 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -36,6 +36,11 @@
sub sp, sp, #368
.cfi_adjust_cfa_offset 368
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 368)
+#error "SAVE_ALL_CALLEE_SAVE_FRAME(ARM64) size not as expected."
+#endif
+
// FP args
stp d1, d2, [sp, #8]
stp d2, d3, [sp, #24]
@@ -95,8 +100,61 @@
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(kRefsOnly).
*/
+// WIP.
.macro SETUP_REF_ONLY_CALLEE_SAVE_FRAME
- brk 0
+ adrp x9, :got:_ZN3art7Runtime9instance_E
+ ldr x9, [x9, #:got_lo12:_ZN3art7Runtime9instance_E]
+
+ // Our registers aren't intermixed - just spill in order.
+ ldr x9,[x9] // x9 = & (art::Runtime * art::Runtime.instance_) .
+
+ // x9 = (ArtMethod*) Runtime.instance_.callee_save_methods[kRefAndArgs] .
+ ldr x9, [x9, RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET ]
+
+ sub sp, sp, #176
+ .cfi_adjust_cfa_offset 176
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 176)
+#error "REFS_ONLY_CALLEE_SAVE_FRAME(ARM64) size not as expected."
+#endif
+
+ // FP callee-saves
+ stp d8, d9, [sp, #8]
+ stp d10, d11, [sp, #24]
+ stp d12, d13, [sp, #40]
+ stp d14, d15, [sp, #56]
+
+ // Callee saved.
+ stp xSELF, x19, [sp, #72]
+ .cfi_rel_offset x18, 72
+ .cfi_rel_offset x19, 80
+
+ stp x20, x21, [sp, #88]
+ .cfi_rel_offset x20, 88
+ .cfi_rel_offset x21, 96
+
+ stp x22, x23, [sp, #104]
+ .cfi_rel_offset x22, 104
+ .cfi_rel_offset x23, 112
+
+ stp x24, x25, [sp, #120]
+ .cfi_rel_offset x24, 120
+ .cfi_rel_offset x25, 128
+
+ stp x26, x27, [sp, #136]
+ .cfi_rel_offset x26, 136
+ .cfi_rel_offset x27, 144
+
+ stp x28, xFP, [sp, #152] // Save FP.
+ .cfi_rel_offset x28, 152
+ .cfi_rel_offset x29, 160
+
+ str xLR, [sp, #168]
+ .cfi_rel_offset x30, 168
+
+ // Loads appropriate callee-save-method
+ str x9, [sp] // Store ArtMethod* Runtime::callee_save_methods_[kRefsAndArgs]
.endm
.macro RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
@@ -112,6 +170,11 @@
sub sp, sp, #304
.cfi_adjust_cfa_offset 304
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 304)
+#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(ARM64) size not as expected."
+#endif
+
stp d0, d1, [sp, #16]
stp d2, d3, [sp, #32]
stp d4, d5, [sp, #48]
@@ -325,10 +388,14 @@
DELIVER_PENDING_EXCEPTION
.endm
+// FIXME: Temporary fix for TR(XSELF).
.macro NO_ARG_RUNTIME_EXCEPTION c_name, cxx_name
.extern \cxx_name
ENTRY \c_name
- brk 0
+ SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
+ mov x0, x19 // pass Thread::Current
+ mov x1, sp // pass SP
+ b \cxx_name // \cxx_name(Thread*, SP)
END \c_name
.endm
@@ -339,15 +406,19 @@ ENTRY \c_name
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context.
mov x1, x19 // pass Thread::Current.
mov x2, sp // pass SP.
- b \cxx_name // \cxx_name(Thread*, SP).
+ b \cxx_name // \cxx_name(arg, Thread*, SP).
brk 0
END \c_name
.endm
+// FIXME: Temporary fix for TR(XSELF).
.macro TWO_ARG_RUNTIME_EXCEPTION c_name, cxx_name
.extern \cxx_name
ENTRY \c_name
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
+ mov x2, x19 // pass Thread::Current
+ mov x3, sp // pass SP
+ b \cxx_name // \cxx_name(arg1, arg2, Thread*, SP)
brk 0
END \c_name
.endm
diff --git a/runtime/arch/mips/asm_support_mips.S b/runtime/arch/mips/asm_support_mips.S
index d110b95..d8ec9cd 100644
--- a/runtime/arch/mips/asm_support_mips.S
+++ b/runtime/arch/mips/asm_support_mips.S
@@ -19,6 +19,14 @@
#include "asm_support_mips.h"
+// Define special registers.
+
+// Register holding suspend check count down.
+#define rSUSPEND $s0
+// Register holding Thread::Current().
+#define rSELF $s1
+
+
/* Cache alignment for function entry */
.macro ENTRY name
.type \name, %function
diff --git a/runtime/arch/mips/asm_support_mips.h b/runtime/arch/mips/asm_support_mips.h
index 36ce1b6..2b4a745 100644
--- a/runtime/arch/mips/asm_support_mips.h
+++ b/runtime/arch/mips/asm_support_mips.h
@@ -19,10 +19,6 @@
#include "asm_support.h"
-// Register holding suspend check count down.
-#define rSUSPEND $s0
-// Register holding Thread::Current().
-#define rSELF $s1
// Offset of field Thread::tls32_.state_and_flags verified in InitCpu
#define THREAD_FLAGS_OFFSET 0
// Offset of field Thread::tlsPtr_.card_table verified in InitCpu
@@ -30,4 +26,8 @@
// Offset of field Thread::tlsPtr_.exception verified in InitCpu
#define THREAD_EXCEPTION_OFFSET 116
+#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 64
+#define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 64
+#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 64
+
#endif // ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index c3ae563..95fcd73 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -34,6 +34,12 @@
.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
addiu $sp, $sp, -64
.cfi_adjust_cfa_offset 64
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 64)
+#error "SAVE_ALL_CALLEE_SAVE_FRAME(MIPS) size not as expected."
+#endif
+
sw $ra, 60($sp)
.cfi_rel_offset 31, 60
sw $s8, 56($sp)
@@ -68,6 +74,12 @@
.macro SETUP_REF_ONLY_CALLEE_SAVE_FRAME
addiu $sp, $sp, -64
.cfi_adjust_cfa_offset 64
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 64)
+#error "REFS_ONLY_CALLEE_SAVE_FRAME(MIPS) size not as expected."
+#endif
+
sw $ra, 60($sp)
.cfi_rel_offset 31, 60
sw $s8, 56($sp)
@@ -144,6 +156,12 @@
.macro SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
addiu $sp, $sp, -64
.cfi_adjust_cfa_offset 64
+
+ // Ugly compile-time check, but we only have the preprocessor.
+#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 64)
+#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(MIPS) size not as expected."
+#endif
+
sw $ra, 60($sp)
.cfi_rel_offset 31, 60
sw $s8, 56($sp)
diff --git a/runtime/arch/x86/asm_support_x86.h b/runtime/arch/x86/asm_support_x86.h
index e986c41..fd5ed5a 100644
--- a/runtime/arch/x86/asm_support_x86.h
+++ b/runtime/arch/x86/asm_support_x86.h
@@ -28,4 +28,8 @@
// Offset of field Thread::thin_lock_thread_id_ verified in InitCpu
#define THREAD_ID_OFFSET 12
+#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 32
+#define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 32
+#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 32
+
#endif // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 12460b9..339ed2e 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -28,6 +28,11 @@ MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
PUSH ebp
subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
CFI_ADJUST_CFA_OFFSET(16)
+ // Ugly compile-time check, but we only have the preprocessor.
+ // Last +4: implicit return address pushed on stack when caller made call.
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 3*4 + 16 + 4)
+#error "SAVE_ALL_CALLEE_SAVE_FRAME(X86) size not as expected."
+#endif
END_MACRO
/*
@@ -40,6 +45,12 @@ MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
PUSH ebp
subl MACRO_LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
CFI_ADJUST_CFA_OFFSET(16)
+
+ // Ugly compile-time check, but we only have the preprocessor.
+ // Last +4: implicit return address pushed on stack when caller made call.
+#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 3*4 + 16 + 4)
+#error "REFS_ONLY_CALLEE_SAVE_FRAME(X86) size not as expected."
+#endif
END_MACRO
MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
@@ -62,6 +73,12 @@ MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
PUSH edx
PUSH ecx
PUSH eax // Align stack, eax will be clobbered by Method*
+
+ // Ugly compile-time check, but we only have the preprocessor.
+ // Last +4: implicit return address pushed on stack when caller made call.
+#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 7*4 + 4)
+#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(X86) size not as expected."
+#endif
END_MACRO
MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)
diff --git a/runtime/arch/x86_64/asm_support_x86_64.S b/runtime/arch/x86_64/asm_support_x86_64.S
index a9f69f5..ad65033 100644
--- a/runtime/arch/x86_64/asm_support_x86_64.S
+++ b/runtime/arch/x86_64/asm_support_x86_64.S
@@ -19,15 +19,15 @@
#include "asm_support_x86_64.h"
-#if defined(__clang__)
- // Clang's as(1) doesn't let you name macro parameters.
+#if defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 5)
+ // Clang's as(1) doesn't let you name macro parameters prior to 3.5.
#define MACRO0(macro_name) .macro macro_name
#define MACRO1(macro_name, macro_arg1) .macro macro_name
#define MACRO2(macro_name, macro_arg1, macro_args2) .macro macro_name
#define MACRO3(macro_name, macro_arg1, macro_args2, macro_args3) .macro macro_name
#define END_MACRO .endmacro
- // Clang's as(1) uses $0, $1, and so on for macro arguments.
+ // Clang's as(1) uses $0, $1, and so on for macro arguments prior to 3.5.
#define VAR(name,index) SYMBOL($index)
#define PLT_VAR(name, index) SYMBOL($index)@PLT
#define REG_VAR(name,index) %$index
diff --git a/runtime/arch/x86_64/asm_support_x86_64.h b/runtime/arch/x86_64/asm_support_x86_64.h
index 70ef3ef..109533b 100644
--- a/runtime/arch/x86_64/asm_support_x86_64.h
+++ b/runtime/arch/x86_64/asm_support_x86_64.h
@@ -35,4 +35,8 @@
// Offset of field Thread::thin_lock_thread_id_ verified in InitCpu
#define THREAD_ID_OFFSET 12
+#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 64
+#define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 64
+#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 176
+
#endif // ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 4951ad0..a31ea58 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -39,6 +39,12 @@ MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
movq RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10
// Store ArtMethod* to bottom of stack.
movq %r10, 0(%rsp)
+
+ // Ugly compile-time check, but we only have the preprocessor.
+ // Last +8: implicit return address pushed on stack when caller made call.
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 6*8 + 8 + 8)
+#error "SAVE_ALL_CALLEE_SAVE_FRAME(X86_64) size not as expected."
+#endif
END_MACRO
/*
@@ -63,6 +69,12 @@ MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
movq RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10
// Store ArtMethod* to bottom of stack.
movq %r10, 0(%rsp)
+
+ // Ugly compile-time check, but we only have the preprocessor.
+ // Last +8: implicit return address pushed on stack when caller made call.
+#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 6*8 + 8 + 8)
+#error "REFS_ONLY_CALLEE_SAVE_FRAME(X86_64) size not as expected."
+#endif
END_MACRO
MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
@@ -114,6 +126,12 @@ MACRO0(SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME)
movq %xmm7, 72(%rsp)
// Store ArtMethod* to bottom of stack.
movq %r10, 0(%rsp)
+
+ // Ugly compile-time check, but we only have the preprocessor.
+ // Last +8: implicit return address pushed on stack when caller made call.
+#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 11*8 + 80 + 8)
+#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(X86_64) size not as expected."
+#endif
END_MACRO
MACRO0(RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME)