diff options
author | 2017-08-07 21:55:19 +0000 | |
---|---|---|
committer | 2017-08-07 21:55:19 +0000 | |
commit | 3b21019edb5586a73516833482fc203e75309dbe (patch) | |
tree | fcef5458a721bad3d51d3fd1e1b614c7ec61fc81 | |
parent | a7c29837831c82e849036ea6f8018115c16dbb78 (diff) | |
parent | 0a87a653a296854c9a0abacd9bb1557ee4c4d05d (diff) |
Merge "Add two special runtime methods."
29 files changed, 218 insertions, 65 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 9e4971ce75..115e722a75 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -1686,6 +1686,10 @@ void ImageWriter::CalculateNewObjectOffsets() { runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs); image_methods_[ImageHeader::kSaveEverythingMethod] = runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything); + image_methods_[ImageHeader::kSaveEverythingMethodForClinit] = + runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForClinit); + image_methods_[ImageHeader::kSaveEverythingMethodForSuspendCheck] = + runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForSuspendCheck); // Visit image methods first to have the main runtime methods in the first image. for (auto* m : image_methods_) { CHECK(m != nullptr); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 99168c9bc5..f8b1f5375a 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -89,6 +89,8 @@ const char* image_methods_descriptions_[] = { "kSaveRefsOnlyMethod", "kSaveRefsAndArgsMethod", "kSaveEverythingMethod", + "kSaveEverythingMethodForClinit", + "kSaveEverythingMethodForSuspendCheck", }; const char* image_roots_descriptions_[] = { diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc index bfac8c422d..1ba4070056 100644 --- a/runtime/arch/arch_test.cc +++ b/runtime/arch/arch_test.cc @@ -88,6 +88,11 @@ static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY; #undef FRAME_SIZE_SAVE_REFS_ONLY static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS; #undef FRAME_SIZE_SAVE_REFS_AND_ARGS +static constexpr size_t kFrameSizeSaveEverythingForClinit = FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT +static constexpr size_t kFrameSizeSaveEverythingForSuspendCheck = + FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; #undef FRAME_SIZE_SAVE_EVERYTHING #undef BAKER_MARK_INTROSPECTION_FIELD_LDR_NARROW_ENTRYPOINT_OFFSET @@ -109,6 +114,11 @@ static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY; #undef FRAME_SIZE_SAVE_REFS_ONLY static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS; #undef FRAME_SIZE_SAVE_REFS_AND_ARGS +static constexpr size_t kFrameSizeSaveEverythingForClinit = FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT +static constexpr size_t kFrameSizeSaveEverythingForSuspendCheck = + FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; #undef FRAME_SIZE_SAVE_EVERYTHING #undef BAKER_MARK_INTROSPECTION_ARRAY_SWITCH_OFFSET @@ -126,6 +136,11 @@ static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY; #undef FRAME_SIZE_SAVE_REFS_ONLY static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS; #undef FRAME_SIZE_SAVE_REFS_AND_ARGS +static constexpr size_t kFrameSizeSaveEverythingForClinit = FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT +static constexpr size_t kFrameSizeSaveEverythingForSuspendCheck = + FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; #undef FRAME_SIZE_SAVE_EVERYTHING #undef BAKER_MARK_INTROSPECTION_REGISTER_COUNT @@ -142,6 +157,11 @@ static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY; #undef FRAME_SIZE_SAVE_REFS_ONLY static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS; #undef FRAME_SIZE_SAVE_REFS_AND_ARGS +static constexpr size_t kFrameSizeSaveEverythingForClinit = FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT +static constexpr size_t kFrameSizeSaveEverythingForSuspendCheck = + FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; #undef FRAME_SIZE_SAVE_EVERYTHING #undef BAKER_MARK_INTROSPECTION_REGISTER_COUNT @@ -158,6 +178,11 @@ static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY; #undef FRAME_SIZE_SAVE_REFS_ONLY static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS; #undef FRAME_SIZE_SAVE_REFS_AND_ARGS +static constexpr size_t kFrameSizeSaveEverythingForClinit = FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT +static constexpr size_t kFrameSizeSaveEverythingForSuspendCheck = + FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; #undef FRAME_SIZE_SAVE_EVERYTHING } // namespace x86 @@ -170,25 +195,36 @@ static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY; #undef FRAME_SIZE_SAVE_REFS_ONLY static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS; #undef FRAME_SIZE_SAVE_REFS_AND_ARGS +static constexpr size_t kFrameSizeSaveEverythingForClinit = FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT +static constexpr size_t kFrameSizeSaveEverythingForSuspendCheck = + FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK; +#undef FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING; #undef FRAME_SIZE_SAVE_EVERYTHING } // namespace x86_64 // Check architecture specific constants are sound. -#define TEST_ARCH(Arch, arch) \ - TEST_F(ArchTest, Arch) { \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveAllCalleeSaves, \ - arch::kFrameSizeSaveAllCalleeSaves); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveRefsOnly, \ - arch::kFrameSizeSaveRefsOnly); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveRefsAndArgs, \ - arch::kFrameSizeSaveRefsAndArgs); \ - CheckFrameSize(InstructionSet::k##Arch, \ - CalleeSaveType::kSaveEverything, \ - arch::kFrameSizeSaveEverything); \ +#define TEST_ARCH(Arch, arch) \ + TEST_F(ArchTest, Arch) { \ + CheckFrameSize(InstructionSet::k##Arch, \ + CalleeSaveType::kSaveAllCalleeSaves, \ + arch::kFrameSizeSaveAllCalleeSaves); \ + CheckFrameSize(InstructionSet::k##Arch, \ + CalleeSaveType::kSaveRefsOnly, \ + arch::kFrameSizeSaveRefsOnly); \ + CheckFrameSize(InstructionSet::k##Arch, \ + CalleeSaveType::kSaveRefsAndArgs, \ + arch::kFrameSizeSaveRefsAndArgs); \ + CheckFrameSize(InstructionSet::k##Arch, \ + CalleeSaveType::kSaveEverything, \ + arch::kFrameSizeSaveEverything); \ + CheckFrameSize(InstructionSet::k##Arch, \ + CalleeSaveType::kSaveEverythingForClinit, \ + arch::kFrameSizeSaveEverythingForClinit); \ + CheckFrameSize(InstructionSet::k##Arch, \ + CalleeSaveType::kSaveEverythingForSuspendCheck, \ + arch::kFrameSizeSaveEverythingForSuspendCheck); \ } TEST_ARCH(Arm, arm) TEST_ARCH(Arm64, arm64) diff --git a/runtime/arch/arm/asm_support_arm.h b/runtime/arch/arm/asm_support_arm.h index 8f2fd6ecc9..3d85872617 100644 --- a/runtime/arch/arm/asm_support_arm.h +++ b/runtime/arch/arm/asm_support_arm.h @@ -23,6 +23,8 @@ #define FRAME_SIZE_SAVE_REFS_ONLY 32 #define FRAME_SIZE_SAVE_REFS_AND_ARGS 112 #define FRAME_SIZE_SAVE_EVERYTHING 192 +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT FRAME_SIZE_SAVE_EVERYTHING +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK FRAME_SIZE_SAVE_EVERYTHING // The offset from the art_quick_read_barrier_mark_introspection (used for field // loads with 32-bit LDR) to the entrypoint for field loads with 16-bit LDR, diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 375768ec3f..cf2bfeeeef 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -182,7 +182,7 @@ * Runtime::CreateCalleeSaveMethod(kSaveEverything) * when core registers are already saved. */ -.macro SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED rTemp +.macro SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED rTemp, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET @ 14 words of callee saves and args already saved. vpush {d0-d15} @ 32 words, 2 for each of the 16 saved doubles. .cfi_adjust_cfa_offset 128 @@ -190,7 +190,7 @@ .cfi_adjust_cfa_offset 8 RUNTIME_CURRENT1 \rTemp @ Load Runtime::Current into rTemp. @ Load kSaveEverything Method* into rTemp. - ldr \rTemp, [\rTemp, #RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET] + ldr \rTemp, [\rTemp, #\runtime_method_offset] str \rTemp, [sp, #0] @ Place Method* at bottom of stack. str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame. @@ -204,7 +204,7 @@ * Macro that sets up the callee save frame to conform with * Runtime::CreateCalleeSaveMethod(kSaveEverything) */ -.macro SETUP_SAVE_EVERYTHING_FRAME rTemp +.macro SETUP_SAVE_EVERYTHING_FRAME rTemp, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET push {r0-r12, lr} @ 14 words of callee saves and args. .cfi_adjust_cfa_offset 56 .cfi_rel_offset r0, 0 @@ -221,7 +221,7 @@ .cfi_rel_offset r11, 44 .cfi_rel_offset ip, 48 .cfi_rel_offset lr, 52 - SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED \rTemp + SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED \rTemp, \runtime_method_offset .endm .macro RESTORE_SAVE_EVERYTHING_FRAME @@ -1004,10 +1004,10 @@ END \name .endm // Macro for string and type resolution and initialization. -.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint +.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET .extern \entrypoint ENTRY \name - SETUP_SAVE_EVERYTHING_FRAME r1 @ save everything in case of GC + SETUP_SAVE_EVERYTHING_FRAME r1, \runtime_method_offset @ save everything in case of GC mov r1, r9 @ pass Thread::Current bl \entrypoint @ (uint32_t index, Thread*) cbz r0, 1f @ If result is null, deliver the OOME. @@ -1021,8 +1021,12 @@ ENTRY \name END \name .endm -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode +.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT name, entrypoint + ONE_ARG_SAVE_EVERYTHING_DOWNCALL \name, \entrypoint, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET +.endm + +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode @@ -1537,7 +1541,7 @@ ENTRY art_quick_test_suspend 1: mov rSUSPEND, #SUSPEND_CHECK_INTERVAL @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL #endif - SETUP_SAVE_EVERYTHING_FRAME r0 @ save everything for GC stack crawl + SETUP_SAVE_EVERYTHING_FRAME r0, RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET @ save everything for GC stack crawl mov r0, rSELF bl artTestSuspendFromCode @ (Thread*) RESTORE_SAVE_EVERYTHING_FRAME diff --git a/runtime/arch/arm/quick_method_frame_info_arm.h b/runtime/arch/arm/quick_method_frame_info_arm.h index 39061f0d4d..5c5b81baae 100644 --- a/runtime/arch/arm/quick_method_frame_info_arm.h +++ b/runtime/arch/arm/quick_method_frame_info_arm.h @@ -56,6 +56,7 @@ static constexpr uint32_t kArmCalleeSaveFpEverythingSpills = kArmCalleeSaveFpArgSpills | kArmCalleeSaveFpAllSpills; constexpr uint32_t ArmCalleeSaveCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kArmCalleeSaveAlwaysSpills | kArmCalleeSaveRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kArmCalleeSaveArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kArmCalleeSaveAllSpills : 0) | @@ -63,6 +64,7 @@ constexpr uint32_t ArmCalleeSaveCoreSpills(CalleeSaveType type) { } constexpr uint32_t ArmCalleeSaveFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kArmCalleeSaveFpAlwaysSpills | kArmCalleeSaveFpRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kArmCalleeSaveFpArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kArmCalleeSaveFpAllSpills : 0) | @@ -70,29 +72,34 @@ constexpr uint32_t ArmCalleeSaveFpSpills(CalleeSaveType type) { } constexpr uint32_t ArmCalleeSaveFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return RoundUp((POPCOUNT(ArmCalleeSaveCoreSpills(type)) /* gprs */ + POPCOUNT(ArmCalleeSaveFpSpills(type)) /* fprs */ + 1 /* Method* */) * static_cast<size_t>(kArmPointerSize), kStackAlignment); } constexpr QuickMethodFrameInfo ArmCalleeSaveMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return QuickMethodFrameInfo(ArmCalleeSaveFrameSize(type), ArmCalleeSaveCoreSpills(type), ArmCalleeSaveFpSpills(type)); } constexpr size_t ArmCalleeSaveFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return ArmCalleeSaveFrameSize(type) - (POPCOUNT(ArmCalleeSaveCoreSpills(type)) + POPCOUNT(ArmCalleeSaveFpSpills(type))) * static_cast<size_t>(kArmPointerSize); } constexpr size_t ArmCalleeSaveGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return ArmCalleeSaveFrameSize(type) - POPCOUNT(ArmCalleeSaveCoreSpills(type)) * static_cast<size_t>(kArmPointerSize); } constexpr size_t ArmCalleeSaveLrOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return ArmCalleeSaveFrameSize(type) - POPCOUNT(ArmCalleeSaveCoreSpills(type) & (-(1 << LR))) * static_cast<size_t>(kArmPointerSize); } diff --git a/runtime/arch/arm64/asm_support_arm64.h b/runtime/arch/arm64/asm_support_arm64.h index 6b7720023e..57376d0c4f 100644 --- a/runtime/arch/arm64/asm_support_arm64.h +++ b/runtime/arch/arm64/asm_support_arm64.h @@ -23,6 +23,8 @@ #define FRAME_SIZE_SAVE_REFS_ONLY 96 #define FRAME_SIZE_SAVE_REFS_AND_ARGS 224 #define FRAME_SIZE_SAVE_EVERYTHING 512 +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT FRAME_SIZE_SAVE_EVERYTHING +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK FRAME_SIZE_SAVE_EVERYTHING // The offset from art_quick_read_barrier_mark_introspection to the array switch cases, // i.e. art_quick_read_barrier_mark_introspection_arrays. diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index d15f5b85ec..3d8ca402cf 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -287,7 +287,7 @@ * when the SP has already been decremented by FRAME_SIZE_SAVE_EVERYTHING * and saving registers x29 and LR is handled elsewhere. */ -.macro SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP_SKIP_X29_LR +.macro SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP_SKIP_X29_LR runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET // Ugly compile-time check, but we only have the preprocessor. #if (FRAME_SIZE_SAVE_EVERYTHING != 512) #error "FRAME_SIZE_SAVE_EVERYTHING(ARM64) size not as expected." @@ -337,7 +337,7 @@ ldr xIP0, [xIP0] // art::Runtime* xIP0 = art::Runtime::instance_; // ArtMethod* xIP0 = Runtime::instance_->callee_save_methods_[kSaveEverything]; - ldr xIP0, [xIP0, RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET] + ldr xIP0, [xIP0, \runtime_method_offset] // Store ArtMethod* Runtime::callee_save_methods_[kSaveEverything]. str xIP0, [sp] @@ -350,10 +350,10 @@ * Macro that sets up the callee save frame to conform with * Runtime::CreateCalleeSaveMethod(kSaveEverything) */ -.macro SETUP_SAVE_EVERYTHING_FRAME +.macro SETUP_SAVE_EVERYTHING_FRAME runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET INCREASE_FRAME 512 SAVE_TWO_REGS x29, xLR, 496 - SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP_SKIP_X29_LR + SETUP_SAVE_EVERYTHING_FRAME_DECREMENTED_SP_SKIP_X29_LR \runtime_method_offset .endm .macro RESTORE_SAVE_EVERYTHING_FRAME_KEEP_X0 @@ -398,7 +398,7 @@ .endm .macro RESTORE_SAVE_EVERYTHING_FRAME - RESTORE_REG x0, 264 + RESTORE_REG x0, 264 RESTORE_SAVE_EVERYTHING_FRAME_KEEP_X0 .endm @@ -1593,10 +1593,10 @@ END \name .endm // Macro for string and type resolution and initialization. -.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint +.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET .extern \entrypoint ENTRY \name - SETUP_SAVE_EVERYTHING_FRAME // save everything for stack crawl + SETUP_SAVE_EVERYTHING_FRAME \runtime_method_offset // save everything for stack crawl mov x1, xSELF // pass Thread::Current bl \entrypoint // (int32_t index, Thread* self) cbz w0, 1f // If result is null, deliver the OOME. @@ -1611,6 +1611,10 @@ ENTRY \name END \name .endm +.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT name, entrypoint + ONE_ARG_SAVE_EVERYTHING_DOWNCALL \name, \entrypoint, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET +.endm + .macro RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER cbz w0, 1f // result zero branch over ret // return @@ -1629,9 +1633,8 @@ TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, * initializer and deliver the exception on error. On success the static storage base is * returned. */ -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode - -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode @@ -2008,7 +2011,7 @@ GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFr */ .extern artTestSuspendFromCode ENTRY art_quick_test_suspend - SETUP_SAVE_EVERYTHING_FRAME // save callee saves for stack crawl + SETUP_SAVE_EVERYTHING_FRAME RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET // save callee saves for stack crawl mov x0, xSELF bl artTestSuspendFromCode // (Thread*) RESTORE_SAVE_EVERYTHING_FRAME diff --git a/runtime/arch/arm64/quick_method_frame_info_arm64.h b/runtime/arch/arm64/quick_method_frame_info_arm64.h index c231d4d3d4..3e6f6c6e3b 100644 --- a/runtime/arch/arm64/quick_method_frame_info_arm64.h +++ b/runtime/arch/arm64/quick_method_frame_info_arm64.h @@ -80,6 +80,7 @@ static constexpr uint32_t kArm64CalleeSaveFpEverythingSpills = (1 << art::arm64::D30) | (1 << art::arm64::D31); constexpr uint32_t Arm64CalleeSaveCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kArm64CalleeSaveAlwaysSpills | kArm64CalleeSaveRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kArm64CalleeSaveArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kArm64CalleeSaveAllSpills : 0) | @@ -87,6 +88,7 @@ constexpr uint32_t Arm64CalleeSaveCoreSpills(CalleeSaveType type) { } constexpr uint32_t Arm64CalleeSaveFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kArm64CalleeSaveFpAlwaysSpills | kArm64CalleeSaveFpRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kArm64CalleeSaveFpArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kArm64CalleeSaveFpAllSpills : 0) | @@ -94,29 +96,34 @@ constexpr uint32_t Arm64CalleeSaveFpSpills(CalleeSaveType type) { } constexpr uint32_t Arm64CalleeSaveFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return RoundUp((POPCOUNT(Arm64CalleeSaveCoreSpills(type)) /* gprs */ + POPCOUNT(Arm64CalleeSaveFpSpills(type)) /* fprs */ + 1 /* Method* */) * static_cast<size_t>(kArm64PointerSize), kStackAlignment); } constexpr QuickMethodFrameInfo Arm64CalleeSaveMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return QuickMethodFrameInfo(Arm64CalleeSaveFrameSize(type), Arm64CalleeSaveCoreSpills(type), Arm64CalleeSaveFpSpills(type)); } constexpr size_t Arm64CalleeSaveFpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return Arm64CalleeSaveFrameSize(type) - (POPCOUNT(Arm64CalleeSaveCoreSpills(type)) + POPCOUNT(Arm64CalleeSaveFpSpills(type))) * static_cast<size_t>(kArm64PointerSize); } constexpr size_t Arm64CalleeSaveGpr1Offset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return Arm64CalleeSaveFrameSize(type) - POPCOUNT(Arm64CalleeSaveCoreSpills(type)) * static_cast<size_t>(kArm64PointerSize); } constexpr size_t Arm64CalleeSaveLrOffset(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return Arm64CalleeSaveFrameSize(type) - POPCOUNT(Arm64CalleeSaveCoreSpills(type) & (-(1 << LR))) * static_cast<size_t>(kArm64PointerSize); diff --git a/runtime/arch/mips/asm_support_mips.h b/runtime/arch/mips/asm_support_mips.h index 9d8572ffb5..2edd63f58a 100644 --- a/runtime/arch/mips/asm_support_mips.h +++ b/runtime/arch/mips/asm_support_mips.h @@ -23,6 +23,8 @@ #define FRAME_SIZE_SAVE_REFS_ONLY 48 #define FRAME_SIZE_SAVE_REFS_AND_ARGS 112 #define FRAME_SIZE_SAVE_EVERYTHING 256 +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT FRAME_SIZE_SAVE_EVERYTHING +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK FRAME_SIZE_SAVE_EVERYTHING // &art_quick_read_barrier_mark_introspection is the first of many entry points: // 21 entry points for long field offsets, large array indices and variable array indices diff --git a/runtime/arch/mips/quick_method_frame_info_mips.h b/runtime/arch/mips/quick_method_frame_info_mips.h index 01879a5cea..45a21ab942 100644 --- a/runtime/arch/mips/quick_method_frame_info_mips.h +++ b/runtime/arch/mips/quick_method_frame_info_mips.h @@ -65,6 +65,7 @@ static constexpr uint32_t kMipsCalleeSaveFpEverythingSpills = (1 << art::mips::F28) | (1 << art::mips::F29) | (1 << art::mips::F30) | (1u << art::mips::F31); constexpr uint32_t MipsCalleeSaveCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kMipsCalleeSaveAlwaysSpills | kMipsCalleeSaveRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kMipsCalleeSaveArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kMipsCalleeSaveAllSpills : 0) | @@ -72,6 +73,7 @@ constexpr uint32_t MipsCalleeSaveCoreSpills(CalleeSaveType type) { } constexpr uint32_t MipsCalleeSaveFPSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kMipsCalleeSaveFpAlwaysSpills | kMipsCalleeSaveFpRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kMipsCalleeSaveFpArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kMipsCalleeSaveAllFPSpills : 0) | @@ -79,12 +81,14 @@ constexpr uint32_t MipsCalleeSaveFPSpills(CalleeSaveType type) { } constexpr uint32_t MipsCalleeSaveFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return RoundUp((POPCOUNT(MipsCalleeSaveCoreSpills(type)) /* gprs */ + POPCOUNT(MipsCalleeSaveFPSpills(type)) /* fprs */ + 1 /* Method* */) * static_cast<size_t>(kMipsPointerSize), kStackAlignment); } constexpr QuickMethodFrameInfo MipsCalleeSaveMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return QuickMethodFrameInfo(MipsCalleeSaveFrameSize(type), MipsCalleeSaveCoreSpills(type), MipsCalleeSaveFPSpills(type)); diff --git a/runtime/arch/mips64/asm_support_mips64.h b/runtime/arch/mips64/asm_support_mips64.h index 7185da550c..a8e907eca5 100644 --- a/runtime/arch/mips64/asm_support_mips64.h +++ b/runtime/arch/mips64/asm_support_mips64.h @@ -27,6 +27,8 @@ #define FRAME_SIZE_SAVE_REFS_AND_ARGS 208 // $f0-$f31, $at, $v0-$v1, $a0-$a7, $t0-$t3, $s0-$s7, $t8-$t9, $gp, $s8, $ra + padding + method* #define FRAME_SIZE_SAVE_EVERYTHING 496 +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT FRAME_SIZE_SAVE_EVERYTHING +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK FRAME_SIZE_SAVE_EVERYTHING // &art_quick_read_barrier_mark_introspection is the first of many entry points: // 20 entry points for long field offsets, large array indices and variable array indices diff --git a/runtime/arch/mips64/quick_method_frame_info_mips64.h b/runtime/arch/mips64/quick_method_frame_info_mips64.h index a55ab0e196..520f6319d5 100644 --- a/runtime/arch/mips64/quick_method_frame_info_mips64.h +++ b/runtime/arch/mips64/quick_method_frame_info_mips64.h @@ -72,6 +72,7 @@ static constexpr uint32_t kMips64CalleeSaveFpEverythingSpills = (1 << art::mips64::F30) | (1 << art::mips64::F31); constexpr uint32_t Mips64CalleeSaveCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kMips64CalleeSaveAlwaysSpills | kMips64CalleeSaveRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kMips64CalleeSaveArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kMips64CalleeSaveAllSpills : 0) | @@ -79,6 +80,7 @@ constexpr uint32_t Mips64CalleeSaveCoreSpills(CalleeSaveType type) { } constexpr uint32_t Mips64CalleeSaveFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kMips64CalleeSaveFpRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kMips64CalleeSaveFpArgSpills : 0) | (type == CalleeSaveType::kSaveAllCalleeSaves ? kMips64CalleeSaveFpAllSpills : 0) | @@ -86,12 +88,14 @@ constexpr uint32_t Mips64CalleeSaveFpSpills(CalleeSaveType type) { } constexpr uint32_t Mips64CalleeSaveFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return RoundUp((POPCOUNT(Mips64CalleeSaveCoreSpills(type)) /* gprs */ + POPCOUNT(Mips64CalleeSaveFpSpills(type)) /* fprs */ + + 1 /* Method* */) * static_cast<size_t>(kMips64PointerSize), kStackAlignment); } constexpr QuickMethodFrameInfo Mips64CalleeSaveMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return QuickMethodFrameInfo(Mips64CalleeSaveFrameSize(type), Mips64CalleeSaveCoreSpills(type), Mips64CalleeSaveFpSpills(type)); diff --git a/runtime/arch/x86/asm_support_x86.h b/runtime/arch/x86/asm_support_x86.h index 2bba08d571..737d736f01 100644 --- a/runtime/arch/x86/asm_support_x86.h +++ b/runtime/arch/x86/asm_support_x86.h @@ -23,5 +23,7 @@ #define FRAME_SIZE_SAVE_REFS_ONLY 32 #define FRAME_SIZE_SAVE_REFS_AND_ARGS (32 + 32) #define FRAME_SIZE_SAVE_EVERYTHING (48 + 64) +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT FRAME_SIZE_SAVE_EVERYTHING +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK FRAME_SIZE_SAVE_EVERYTHING #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 48d2de9567..4e5e93ac5a 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -226,7 +226,7 @@ END_MACRO * Runtime::CreateCalleeSaveMethod(kSaveEverything) * when EDI and ESI are already saved. */ -MACRO2(SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED, got_reg, temp_reg) +MACRO3(SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED, got_reg, temp_reg, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) // Save core registers from highest to lowest to agree with core spills bitmap. // EDI and ESI, or at least placeholders for them, are already on the stack. PUSH ebp @@ -252,7 +252,7 @@ MACRO2(SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED, got_reg, temp_reg) movl SYMBOL(_ZN3art7Runtime9instance_E)@GOT(REG_VAR(got_reg)), REG_VAR(temp_reg) movl (REG_VAR(temp_reg)), REG_VAR(temp_reg) // Push save everything callee-save method. - pushl RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET(REG_VAR(temp_reg)) + pushl \runtime_method_offset(REG_VAR(temp_reg)) CFI_ADJUST_CFA_OFFSET(4) // Store esp as the stop quick frame. movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET @@ -269,20 +269,20 @@ END_MACRO * Runtime::CreateCalleeSaveMethod(kSaveEverything) * when EDI is already saved. */ -MACRO2(SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED, got_reg, temp_reg) +MACRO3(SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED, got_reg, temp_reg, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) // Save core registers from highest to lowest to agree with core spills bitmap. // EDI, or at least a placeholder for it, is already on the stack. PUSH esi - SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED RAW_VAR(got_reg), RAW_VAR(temp_reg) + SETUP_SAVE_EVERYTHING_FRAME_EDI_ESI_SAVED RAW_VAR(got_reg), RAW_VAR(temp_reg), \runtime_method_offset END_MACRO /* * Macro that sets up the callee save frame to conform with * Runtime::CreateCalleeSaveMethod(kSaveEverything) */ -MACRO2(SETUP_SAVE_EVERYTHING_FRAME, got_reg, temp_reg) +MACRO3(SETUP_SAVE_EVERYTHING_FRAME, got_reg, temp_reg, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) PUSH edi - SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED RAW_VAR(got_reg), RAW_VAR(temp_reg) + SETUP_SAVE_EVERYTHING_FRAME_EDI_SAVED RAW_VAR(got_reg), RAW_VAR(temp_reg), \runtime_method_offset END_MACRO MACRO0(RESTORE_SAVE_EVERYTHING_FRAME_FRPS) @@ -923,9 +923,9 @@ MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) END_MACRO // Macro for string and type resolution and initialization. -MACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name) +MACRO3(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_EVERYTHING_FRAME ebx, ebx // save ref containing registers for GC + SETUP_SAVE_EVERYTHING_FRAME ebx, ebx, \runtime_method_offset // save ref containing registers for GC // Outgoing argument set up subl MACRO_LITERAL(8), %esp // push padding CFI_ADJUST_CFA_OFFSET(8) @@ -947,6 +947,10 @@ MACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name) END_FUNCTION VAR(c_name) END_MACRO +MACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT, c_name, cxx_name) + ONE_ARG_SAVE_EVERYTHING_DOWNCALL \c_name, \cxx_name, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET +END_MACRO + MACRO0(RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER) testl %eax, %eax // eax == 0 ? jz 1f // if eax == 0 goto 1 @@ -1270,8 +1274,8 @@ GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_tlab, artAllocArrayFr GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32 GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64 -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode @@ -1598,7 +1602,7 @@ DEFINE_FUNCTION art_quick_memcpy END_FUNCTION art_quick_memcpy DEFINE_FUNCTION art_quick_test_suspend - SETUP_SAVE_EVERYTHING_FRAME ebx, ebx // save everything for GC + SETUP_SAVE_EVERYTHING_FRAME ebx, ebx, RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET // save everything for GC // Outgoing argument set up subl MACRO_LITERAL(12), %esp // push padding CFI_ADJUST_CFA_OFFSET(12) diff --git a/runtime/arch/x86/quick_method_frame_info_x86.h b/runtime/arch/x86/quick_method_frame_info_x86.h index 8342c9fe03..9a6633365c 100644 --- a/runtime/arch/x86/quick_method_frame_info_x86.h +++ b/runtime/arch/x86/quick_method_frame_info_x86.h @@ -57,23 +57,27 @@ static constexpr uint32_t kX86CalleeSaveFpEverythingSpills = (1 << art::x86::XMM6) | (1 << art::x86::XMM7); constexpr uint32_t X86CalleeSaveCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kX86CalleeSaveAlwaysSpills | kX86CalleeSaveRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveArgSpills : 0) | (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveEverythingSpills : 0); } constexpr uint32_t X86CalleeSaveFpSpills(CalleeSaveType type) { - return (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveFpArgSpills : 0) | - (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveFpEverythingSpills : 0); + type = GetCanonicalCalleeSaveType(type); + return (type == CalleeSaveType::kSaveRefsAndArgs ? kX86CalleeSaveFpArgSpills : 0) | + (type == CalleeSaveType::kSaveEverything ? kX86CalleeSaveFpEverythingSpills : 0); } constexpr uint32_t X86CalleeSaveFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return RoundUp((POPCOUNT(X86CalleeSaveCoreSpills(type)) /* gprs */ + 2 * POPCOUNT(X86CalleeSaveFpSpills(type)) /* fprs */ + 1 /* Method* */) * static_cast<size_t>(kX86PointerSize), kStackAlignment); } constexpr QuickMethodFrameInfo X86CalleeSaveMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return QuickMethodFrameInfo(X86CalleeSaveFrameSize(type), X86CalleeSaveCoreSpills(type), X86CalleeSaveFpSpills(type)); diff --git a/runtime/arch/x86_64/asm_support_x86_64.h b/runtime/arch/x86_64/asm_support_x86_64.h index a4446d3345..51befbe7b8 100644 --- a/runtime/arch/x86_64/asm_support_x86_64.h +++ b/runtime/arch/x86_64/asm_support_x86_64.h @@ -23,5 +23,7 @@ #define FRAME_SIZE_SAVE_REFS_ONLY (64 + 4*8) #define FRAME_SIZE_SAVE_REFS_AND_ARGS (112 + 12*8) #define FRAME_SIZE_SAVE_EVERYTHING (144 + 16*8) +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_CLINIT FRAME_SIZE_SAVE_EVERYTHING +#define FRAME_SIZE_SAVE_EVERYTHING_FOR_SUSPEND_CHECK FRAME_SIZE_SAVE_EVERYTHING #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 0a9199e7e9..73e86100f6 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -272,7 +272,7 @@ END_MACRO * Runtime::CreateCalleeSaveMethod(kSaveEverything) * when R14 and R15 are already saved. */ -MACRO0(SETUP_SAVE_EVERYTHING_FRAME_R14_R15_SAVED) +MACRO1(SETUP_SAVE_EVERYTHING_FRAME_R14_R15_SAVED, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) #if defined(__APPLE__) int3 int3 @@ -316,7 +316,7 @@ MACRO0(SETUP_SAVE_EVERYTHING_FRAME_R14_R15_SAVED) movq %xmm14, 120(%rsp) movq %xmm15, 128(%rsp) // Push ArtMethod* for save everything frame method. - pushq RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET(%r10) + pushq \runtime_method_offset(%r10) CFI_ADJUST_CFA_OFFSET(8) // Store rsp as the top quick frame. movq %rsp, %gs:THREAD_TOP_QUICK_FRAME_OFFSET @@ -334,18 +334,18 @@ END_MACRO * Runtime::CreateCalleeSaveMethod(kSaveEverything) * when R15 is already saved. */ -MACRO0(SETUP_SAVE_EVERYTHING_FRAME_R15_SAVED) +MACRO1(SETUP_SAVE_EVERYTHING_FRAME_R15_SAVED, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) PUSH r14 - SETUP_SAVE_EVERYTHING_FRAME_R14_R15_SAVED + SETUP_SAVE_EVERYTHING_FRAME_R14_R15_SAVED \runtime_method_offset END_MACRO /* * Macro that sets up the callee save frame to conform with * Runtime::CreateCalleeSaveMethod(kSaveEverything) */ -MACRO0(SETUP_SAVE_EVERYTHING_FRAME) +MACRO1(SETUP_SAVE_EVERYTHING_FRAME, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) PUSH r15 - SETUP_SAVE_EVERYTHING_FRAME_R15_SAVED + SETUP_SAVE_EVERYTHING_FRAME_R15_SAVED \runtime_method_offset END_MACRO MACRO0(RESTORE_SAVE_EVERYTHING_FRAME_FRPS) @@ -951,9 +951,9 @@ MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) END_MACRO // Macro for string and type resolution and initialization. -MACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name) +MACRO3(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET) DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_EVERYTHING_FRAME // save everything for GC + SETUP_SAVE_EVERYTHING_FRAME \runtime_method_offset // save everything for GC // Outgoing argument set up movl %eax, %edi // pass string index movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() @@ -970,6 +970,10 @@ MACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name) END_FUNCTION VAR(c_name) END_MACRO +MACRO2(ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT, c_name, cxx_name) + ONE_ARG_SAVE_EVERYTHING_DOWNCALL \c_name, \cxx_name, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET +END_MACRO + MACRO0(RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER) testq %rax, %rax // rax == 0 ? jz 1f // if rax == 0 goto 1 @@ -1290,8 +1294,8 @@ DEFINE_FUNCTION art_quick_alloc_object_initialized_region_tlab ALLOC_OBJECT_TLAB_SLOW_PATH artAllocObjectFromCodeInitializedRegionTLAB END_FUNCTION art_quick_alloc_object_initialized_region_tlab -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode -ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode +ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode @@ -1575,7 +1579,7 @@ DEFINE_FUNCTION art_quick_memcpy END_FUNCTION art_quick_memcpy DEFINE_FUNCTION art_quick_test_suspend - SETUP_SAVE_EVERYTHING_FRAME // save everything for GC + SETUP_SAVE_EVERYTHING_FRAME RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET // save everything for GC // Outgoing argument set up movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current() call SYMBOL(artTestSuspendFromCode) // (Thread*) diff --git a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h b/runtime/arch/x86_64/quick_method_frame_info_x86_64.h index 425d616e76..ebf976ef71 100644 --- a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h +++ b/runtime/arch/x86_64/quick_method_frame_info_x86_64.h @@ -56,24 +56,28 @@ static constexpr uint32_t kX86_64CalleeSaveFpEverythingSpills = (1 << art::x86_64::XMM10) | (1 << art::x86_64::XMM11); constexpr uint32_t X86_64CalleeSaveCoreSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kX86_64CalleeSaveAlwaysSpills | kX86_64CalleeSaveRefSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kX86_64CalleeSaveArgSpills : 0) | (type == CalleeSaveType::kSaveEverything ? kX86_64CalleeSaveEverythingSpills : 0); } constexpr uint32_t X86_64CalleeSaveFpSpills(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return kX86_64CalleeSaveFpSpills | (type == CalleeSaveType::kSaveRefsAndArgs ? kX86_64CalleeSaveFpArgSpills : 0) | (type == CalleeSaveType::kSaveEverything ? kX86_64CalleeSaveFpEverythingSpills : 0); } constexpr uint32_t X86_64CalleeSaveFrameSize(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return RoundUp((POPCOUNT(X86_64CalleeSaveCoreSpills(type)) /* gprs */ + POPCOUNT(X86_64CalleeSaveFpSpills(type)) /* fprs */ + 1 /* Method* */) * static_cast<size_t>(kX86_64PointerSize), kStackAlignment); } constexpr QuickMethodFrameInfo X86_64CalleeSaveMethodFrameInfo(CalleeSaveType type) { + type = GetCanonicalCalleeSaveType(type); return QuickMethodFrameInfo(X86_64CalleeSaveFrameSize(type), X86_64CalleeSaveCoreSpills(type), X86_64CalleeSaveFpSpills(type)); diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index fad927804e..50e91447a9 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -285,6 +285,10 @@ inline const char* ArtMethod::GetName() { return "<runtime internal callee-save reference and argument registers method>"; } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything)) { return "<runtime internal save-every-register method>"; + } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForClinit)) { + return "<runtime internal save-every-register method for clinit>"; + } else if (this == runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForSuspendCheck)) { + return "<runtime internal save-every-register method for suspend check>"; } else { return "<unknown runtime internal method>"; } diff --git a/runtime/base/callee_save_type.h b/runtime/base/callee_save_type.h index 501b296d4f..e9cd63c3a0 100644 --- a/runtime/base/callee_save_type.h +++ b/runtime/base/callee_save_type.h @@ -28,10 +28,20 @@ enum class CalleeSaveType : uint32_t { kSaveRefsOnly, // Only those callee-save registers that can hold references. kSaveRefsAndArgs, // References (see above) and arguments (usually caller-save registers). kSaveEverything, // All registers, including both callee-save and caller-save. + kSaveEverythingForClinit, // Special kSaveEverything for clinit. + kSaveEverythingForSuspendCheck, // Special kSaveEverything for suspend check. kLastCalleeSaveType // Value used for iteration. }; std::ostream& operator<<(std::ostream& os, const CalleeSaveType& rhs); +static inline constexpr CalleeSaveType GetCanonicalCalleeSaveType(CalleeSaveType type) { + if (type == CalleeSaveType::kSaveEverythingForClinit || + type == CalleeSaveType::kSaveEverythingForSuspendCheck) { + return CalleeSaveType::kSaveEverything; + } + return type; +} + } // namespace art #endif // ART_RUNTIME_BASE_CALLEE_SAVE_TYPE_H_ diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc index a2a6e085c2..5355267b07 100644 --- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc @@ -65,8 +65,8 @@ extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, // A class may be accessing another class' fields when it doesn't have access, as access has been // given by inheritance. ScopedQuickEntrypointChecks sqec(self); - auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, - CalleeSaveType::kSaveEverything); + auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod( + self, CalleeSaveType::kSaveEverythingForClinit); ArtMethod* caller = caller_and_outer.caller; mirror::Class* result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, true, false); @@ -80,8 +80,8 @@ extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* s REQUIRES_SHARED(Locks::mutator_lock_) { // Called when method->dex_cache_resolved_types_[] misses. ScopedQuickEntrypointChecks sqec(self); - auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self, - CalleeSaveType::kSaveEverything); + auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod( + self, CalleeSaveType::kSaveEverythingForClinit); ArtMethod* caller = caller_and_outer.caller; mirror::Class* result = ResolveVerifyAndClinit(dex::TypeIndex(type_idx), caller, self, false, false); diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc index 7e08b7ace0..b692618740 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints_test.cc @@ -90,7 +90,18 @@ TEST_F(QuickTrampolineEntrypointsTest, FrameSize) { GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveRefsOnly)); \ CheckFrameSize(isa, \ CalleeSaveType::kSaveAllCalleeSaves, \ - GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveAllCalleeSaves)) + GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveAllCalleeSaves)); \ + CheckFrameSize(isa, \ + CalleeSaveType::kSaveEverything, \ + GetCalleeSaveFrameSize(isa, CalleeSaveType::kSaveEverything)); \ + CheckFrameSize(isa, \ + CalleeSaveType::kSaveEverythingForClinit, \ + GetCalleeSaveFrameSize(isa, \ + CalleeSaveType::kSaveEverythingForClinit)); \ + CheckFrameSize(isa, \ + CalleeSaveType::kSaveEverythingForSuspendCheck, \ + GetCalleeSaveFrameSize( \ + isa, CalleeSaveType::kSaveEverythingForSuspendCheck)) CHECK_FRAME_SIZE(kArm); CHECK_FRAME_SIZE(kArm64); @@ -123,6 +134,13 @@ TEST_F(QuickTrampolineEntrypointsTest, ReturnPC) { GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveRefsOnly)); CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveAllCalleeSaves, GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveAllCalleeSaves)); + CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveEverything, + GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveEverything)); + CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveEverythingForClinit, + GetCalleeSaveReturnPcOffset(kRuntimeISA, CalleeSaveType::kSaveEverythingForClinit)); + CheckPCOffset(kRuntimeISA, CalleeSaveType::kSaveEverythingForSuspendCheck, + GetCalleeSaveReturnPcOffset(kRuntimeISA, + CalleeSaveType::kSaveEverythingForSuspendCheck)); } } // namespace art diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 148438296f..14e017abd9 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -725,6 +725,10 @@ class ImageSpaceLoader { image_header->GetImageMethod(ImageHeader::kSaveRefsAndArgsMethod)); CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything), image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod)); + CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForClinit), + image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForClinit)); + CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForSuspendCheck), + image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForSuspendCheck)); } else if (!runtime->HasResolutionMethod()) { runtime->SetInstructionSet(space->oat_file_non_owned_->GetOatHeader().GetInstructionSet()); runtime->SetResolutionMethod(image_header->GetImageMethod(ImageHeader::kResolutionMethod)); @@ -743,6 +747,12 @@ class ImageSpaceLoader { runtime->SetCalleeSaveMethod( image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod), CalleeSaveType::kSaveEverything); + runtime->SetCalleeSaveMethod( + image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForClinit), + CalleeSaveType::kSaveEverythingForClinit); + runtime->SetCalleeSaveMethod( + image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForSuspendCheck), + CalleeSaveType::kSaveEverythingForSuspendCheck); } VLOG(image) << "ImageSpace::Init exiting " << *space.get(); diff --git a/runtime/generated/asm_support_gen.h b/runtime/generated/asm_support_gen.h index 11b3abb6ed..314c45e117 100644 --- a/runtime/generated/asm_support_gen.h +++ b/runtime/generated/asm_support_gen.h @@ -34,6 +34,10 @@ DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_REFS_ONLY_METHOD_OFFSET), (stat DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::CalleeSaveType::kSaveRefsAndArgs)))) #define RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET 0x18 DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::CalleeSaveType::kSaveEverything)))) +#define RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET 0x20 +DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::CalleeSaveType::kSaveEverythingForClinit)))) +#define RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET 0x28 +DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::CalleeSaveType::kSaveEverythingForSuspendCheck)))) #define THREAD_FLAGS_OFFSET 0 DEFINE_CHECK_EQ(static_cast<int32_t>(THREAD_FLAGS_OFFSET), (static_cast<int32_t>(art::Thread:: ThreadFlagsOffset<art::kRuntimePointerSize>().Int32Value()))) #define THREAD_ID_OFFSET 12 diff --git a/runtime/image.h b/runtime/image.h index 6c76f4915e..7bb796c5a1 100644 --- a/runtime/image.h +++ b/runtime/image.h @@ -183,6 +183,8 @@ class PACKED(4) ImageHeader { kSaveRefsOnlyMethod, kSaveRefsAndArgsMethod, kSaveEverythingMethod, + kSaveEverythingMethodForClinit, + kSaveEverythingMethodForSuspendCheck, kImageMethodsCount, // Number of elements in enum. }; diff --git a/runtime/runtime-inl.h b/runtime/runtime-inl.h index 609f0d658d..4584351a6a 100644 --- a/runtime/runtime-inl.h +++ b/runtime/runtime-inl.h @@ -49,7 +49,9 @@ inline QuickMethodFrameInfo Runtime::GetRuntimeMethodFrameInfo(ArtMethod* method } else if (method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveRefsOnly)) { return GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveRefsOnly); } else { - DCHECK_EQ(method, GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverything)); + DCHECK(method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverything) || + method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverythingForClinit) || + method == GetCalleeSaveMethodUnchecked(CalleeSaveType::kSaveEverythingForSuspendCheck)); return GetCalleeSaveMethodFrameInfo(CalleeSaveType::kSaveEverything); } } diff --git a/runtime/runtime.h b/runtime/runtime.h index 0c1344e11a..4e84468744 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -714,7 +714,7 @@ class Runtime { static constexpr int kProfileForground = 0; static constexpr int kProfileBackground = 1; - static constexpr uint32_t kCalleeSaveSize = 4u; + static constexpr uint32_t kCalleeSaveSize = 6u; // 64 bit so that we can share the same asm offsets for both 32 and 64 bits. uint64_t callee_save_methods_[kCalleeSaveSize]; diff --git a/tools/cpp-define-generator/offset_runtime.def b/tools/cpp-define-generator/offset_runtime.def index 41e7e40af5..1d5ce7dd49 100644 --- a/tools/cpp-define-generator/offset_runtime.def +++ b/tools/cpp-define-generator/offset_runtime.def @@ -40,6 +40,10 @@ DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_REFS_ONLY, art::CalleeSaveType::kSaveRefs DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_REFS_AND_ARGS, art::CalleeSaveType::kSaveRefsAndArgs) // Offset of field Runtime::callee_save_methods_[kSaveEverything] DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_EVERYTHING, art::CalleeSaveType::kSaveEverything) +// Offset of field Runtime::callee_save_methods_[kSaveEverythingForClinit] +DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_EVERYTHING_FOR_CLINIT, art::CalleeSaveType::kSaveEverythingForClinit) +// Offset of field Runtime::callee_save_methods_[kSaveEverythingForSuspendCheck] +DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_EVERYTHING_FOR_SUSPEND_CHECK, art::CalleeSaveType::kSaveEverythingForSuspendCheck) #undef DEFINE_RUNTIME_CALLEE_SAVE_OFFSET #include "common_undef.def" // undef DEFINE_OFFSET_EXPR |