diff options
author | Mathieu Chartier <mathieuc@google.com> | 2018-01-12 14:42:18 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2018-01-13 00:29:43 +0000 |
commit | fa3db3d377bfaceb51c9a97864b17ce02538b7e0 (patch) | |
tree | e499305451300d3a7a9a2c4e86d5392846f889e2 /compiler/optimizing/optimizing_unit_test.h | |
parent | b12293f196dffe3df29a17a054565bac1b578a4f (diff) |
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
Diffstat (limited to 'compiler/optimizing/optimizing_unit_test.h')
-rw-r--r-- | compiler/optimizing/optimizing_unit_test.h | 60 |
1 files changed, 44 insertions, 16 deletions
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 <memory> +#include <vector> + #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<DexFile*>(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<uint8_t*>(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<const DexFile::CodeItem*>(data); + HGraph* CreateCFG(const std::vector<uint16_t>& 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<const DexFile::CodeItem*>(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<mirror::DexCache>(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<std::unique_ptr<const StandardDexFile>> dex_files_; std::unique_ptr<ArenaPoolAndAllocator> pool_and_allocator_; std::unique_ptr<VariableSizedHandleScope> handles_; }; +class OptimizingUnitTest : public CommonCompilerTest, public OptimizingUnitTestHelper {}; + // Naive string diff data type. typedef std::list<std::pair<std::string, std::string>> diff_t; |