From fa3db3d377bfaceb51c9a97864b17ce02538b7e0 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Fri, 12 Jan 2018 14:42:18 -0800 Subject: Change compiler tests to have aligned code item Previously, the code item was not necessarily 32 bit aligned. This caused bus errors on armv7. Also create a real dexfile object instead of casting 0 initialized memory to a dex file pointer. We just got lucky before that the cdex boolean was false. Test: test-art-target-gtest Bug: 63756964 Bug: 71605148 Change-Id: Ic7199f2b97bbd421de1d702efa5c6531ff45c022 --- compiler/optimizing/optimizing_unit_test.h | 60 ++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 16 deletions(-) (limited to 'compiler/optimizing/optimizing_unit_test.h') diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index 8c97d57f4a..6dcbadba6e 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -17,12 +17,16 @@ #ifndef ART_COMPILER_OPTIMIZING_OPTIMIZING_UNIT_TEST_H_ #define ART_COMPILER_OPTIMIZING_OPTIMIZING_UNIT_TEST_H_ +#include +#include + #include "base/scoped_arena_allocator.h" #include "builder.h" #include "common_compiler_test.h" #include "dex/code_item_accessors-inl.h" #include "dex/dex_file.h" #include "dex/dex_instruction.h" +#include "dex/standard_dex_file.h" #include "driver/dex_compilation_unit.h" #include "handle_scope-inl.h" #include "mirror/class_loader.h" @@ -99,18 +103,11 @@ class ArenaPoolAndAllocator { ScopedArenaAllocator scoped_allocator_; }; -inline HGraph* CreateGraph(ArenaPoolAndAllocator* pool_and_allocator) { - return new (pool_and_allocator->GetAllocator()) HGraph( - pool_and_allocator->GetAllocator(), - pool_and_allocator->GetArenaStack(), - *reinterpret_cast(pool_and_allocator->GetAllocator()->Alloc(sizeof(DexFile))), - /*method_idx*/-1, - kRuntimeISA); -} - -class OptimizingUnitTest : public CommonCompilerTest { - protected: - OptimizingUnitTest() : pool_and_allocator_(new ArenaPoolAndAllocator()) { } +// Have a separate helper so the OptimizingCFITest can inherit it without causing +// multiple inheritance errors from having two gtest as a parent twice. +class OptimizingUnitTestHelper { + public: + OptimizingUnitTestHelper() : pool_and_allocator_(new ArenaPoolAndAllocator()) { } ArenaAllocator* GetAllocator() { return pool_and_allocator_->GetAllocator(); } ArenaStack* GetArenaStack() { return pool_and_allocator_->GetArenaStack(); } @@ -122,14 +119,42 @@ class OptimizingUnitTest : public CommonCompilerTest { } HGraph* CreateGraph() { - return art::CreateGraph(pool_and_allocator_.get()); + ArenaAllocator* const allocator = pool_and_allocator_->GetAllocator(); + + // Reserve a big array of 0s so the dex file constructor can offsets from the header. + static constexpr size_t kDexDataSize = 4 * KB; + const uint8_t* dex_data = reinterpret_cast(allocator->Alloc(kDexDataSize)); + + // Create the dex file based on the fake data. Call the constructor so that we can use virtual + // functions. Don't use the arena for the StandardDexFile otherwise the dex location leaks. + dex_files_.emplace_back(new StandardDexFile( + dex_data, + sizeof(StandardDexFile::Header), + "no_location", + /*location_checksum*/ 0, + /*oat_dex_file*/ nullptr, + /*container*/ nullptr)); + + return new (allocator) HGraph( + allocator, + pool_and_allocator_->GetArenaStack(), + *dex_files_.back(), + /*method_idx*/-1, + kRuntimeISA); } // Create a control-flow graph from Dex instructions. - HGraph* CreateCFG(const uint16_t* data, DataType::Type return_type = DataType::Type::kInt32) { - const DexFile::CodeItem* code_item = reinterpret_cast(data); + HGraph* CreateCFG(const std::vector& data, + DataType::Type return_type = DataType::Type::kInt32) { HGraph* graph = CreateGraph(); + // The code item data might not aligned to 4 bytes, copy it to ensure that. + const size_t code_item_size = data.size() * sizeof(data.front()); + void* aligned_data = GetAllocator()->Alloc(code_item_size); + memcpy(aligned_data, &data[0], code_item_size); + CHECK_ALIGNED(aligned_data, StandardDexFile::CodeItem::kAlignment); + const DexFile::CodeItem* code_item = reinterpret_cast(aligned_data); + { ScopedObjectAccess soa(Thread::Current()); if (handles_ == nullptr) { @@ -146,7 +171,7 @@ class OptimizingUnitTest : public CommonCompilerTest { /* access_flags */ 0u, /* verified_method */ nullptr, handles_->NewHandle(nullptr)); - CodeItemDebugInfoAccessor accessor(graph->GetDexFile(), code_item); + CodeItemDebugInfoAccessor accessor(graph->GetDexFile(), code_item, /*dex_method_idx*/ 0u); HGraphBuilder builder(graph, dex_compilation_unit, accessor, handles_.get(), return_type); bool graph_built = (builder.BuildGraph() == kAnalysisSuccess); return graph_built ? graph : nullptr; @@ -154,10 +179,13 @@ class OptimizingUnitTest : public CommonCompilerTest { } private: + std::vector> dex_files_; std::unique_ptr pool_and_allocator_; std::unique_ptr handles_; }; +class OptimizingUnitTest : public CommonCompilerTest, public OptimizingUnitTestHelper {}; + // Naive string diff data type. typedef std::list> diff_t; -- cgit v1.2.3