From 2b03a1f24600c8c9558fb13d3f8bca1ef0f8ee40 Mon Sep 17 00:00:00 2001 From: Roland Levillain Date: Tue, 6 Jun 2017 16:09:59 +0100 Subject: Instrument ARM64 generated code to check the Marking Register. Generate run-time code in the Optimizing compiler checking that the Marking Register's value matches `self.tls32_.is.gc_marking` in debug mode (on target; and on host with JIT, or with AOT when compiling the core image). If a check fails, abort. Test: m test-art-target Test: m test-art-target with tree built with ART_USE_READ_BARRIER=false Test: ARM64 device boot test with libartd. Bug: 37707231 Change-Id: Ie9b322b22b3d26654a06821e1db71dbda3c43061 --- compiler/optimizing/codegen_test_utils.h | 42 +++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'compiler/optimizing/codegen_test_utils.h') diff --git a/compiler/optimizing/codegen_test_utils.h b/compiler/optimizing/codegen_test_utils.h index cada2e679b..bdd105fce7 100644 --- a/compiler/optimizing/codegen_test_utils.h +++ b/compiler/optimizing/codegen_test_utils.h @@ -103,6 +103,40 @@ class TestCodeGeneratorARMVIXL : public arm::CodeGeneratorARMVIXL { }; #endif +#ifdef ART_ENABLE_CODEGEN_arm64 +// Special ARM64 code generator for codegen testing in a limited code +// generation environment (i.e. with no runtime support). +// +// Note: If we want to exercise certains HIR constructions +// (e.g. reference field load in Baker read barrier configuration) in +// codegen tests in the future, we should also: +// - save the Thread Register (X19) and possibly the Marking Register +// (X20) before entering the generated function (both registers are +// callee-save in AAPCS64); +// - set these registers to meaningful values before or upon entering +// the generated function (so that generated code using them is +// correct); +// - restore their original values before leaving the generated +// function. +class TestCodeGeneratorARM64 : public arm64::CodeGeneratorARM64 { + public: + TestCodeGeneratorARM64(HGraph* graph, + const Arm64InstructionSetFeatures& isa_features, + const CompilerOptions& compiler_options) + : arm64::CodeGeneratorARM64(graph, isa_features, compiler_options) {} + + void MaybeGenerateMarkingRegisterCheck(int codem ATTRIBUTE_UNUSED, + Location temp_loc ATTRIBUTE_UNUSED) OVERRIDE { + // When turned on, the marking register checks in + // CodeGeneratorARM64::MaybeGenerateMarkingRegisterCheck expect the + // Thread Register and the Marking Register to be set to + // meaningful values. This is not the case in codegen testing, so + // just disable them entirely here (by doing nothing in this + // method). + } +}; +#endif + #ifdef ART_ENABLE_CODEGEN_x86 class TestCodeGeneratorX86 : public x86::CodeGeneratorX86 { public: @@ -263,7 +297,8 @@ static void RunCode(CodegenTargetConfig target_config, bool has_result, Expected expected) { CompilerOptions compiler_options; - std::unique_ptr codegen(target_config.CreateCodeGenerator(graph, compiler_options)); + std::unique_ptr codegen(target_config.CreateCodeGenerator(graph, + compiler_options)); RunCode(codegen.get(), graph, hook_before_codegen, has_result, expected); } @@ -280,9 +315,8 @@ CodeGenerator* create_codegen_arm_vixl32(HGraph* graph, const CompilerOptions& c CodeGenerator* create_codegen_arm64(HGraph* graph, const CompilerOptions& compiler_options) { std::unique_ptr features_arm64( Arm64InstructionSetFeatures::FromCppDefines()); - return new (graph->GetArena()) arm64::CodeGeneratorARM64(graph, - *features_arm64.get(), - compiler_options); + return new (graph->GetArena()) + TestCodeGeneratorARM64(graph, *features_arm64.get(), compiler_options); } #endif -- cgit v1.2.3-59-g8ed1b