Make RTP::Visit robust against input order

ReferenceTypePropogation::Visit(ArrayRef) relied on the input having a
particular order with known values at the front then topological. This
could cause issues if the list was not properly sorted, causing the
RTP to silently fail. This makes RTP robust against the ordering of
inputs for this function.

Test: ./test.py --host
Bug: 67037140
Change-Id: I03c522ea745f271ce438c82f7c6f3ab476c8249a
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index 703e5f8..8317d7f 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -42,13 +42,13 @@
 
 template<class T> class Handle;
 
-class CommonCompilerTest : public CommonRuntimeTest {
+class CommonCompilerTestImpl {
  public:
   static std::unique_ptr<CompilerOptions> CreateCompilerOptions(InstructionSet instruction_set,
                                                                 const std::string& variant);
 
-  CommonCompilerTest();
-  ~CommonCompilerTest();
+  CommonCompilerTestImpl();
+  virtual ~CommonCompilerTestImpl();
 
   void MakeExecutable(ArtMethod* method, const CompiledMethod* compiled_method)
       REQUIRES_SHARED(Locks::mutator_lock_);
@@ -56,9 +56,9 @@
   static void MakeExecutable(const void* code_start, size_t code_length);
 
  protected:
-  void SetUp() override;
+  void SetUp();
 
-  void SetUpRuntimeOptions(RuntimeOptions* options) override;
+  void SetUpRuntimeOptionsImpl();
 
   Compiler::Kind GetCompilerKind() const;
   void SetCompilerKind(Compiler::Kind compiler_kind);
@@ -67,7 +67,7 @@
     return CompilerFilter::kDefaultCompilerFilter;
   }
 
-  void TearDown() override;
+  void TearDown();
 
   void CompileMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
 
@@ -95,11 +95,46 @@
   std::unique_ptr<CompilerOptions> compiler_options_;
   std::unique_ptr<VerificationResults> verification_results_;
 
+ protected:
+  virtual ClassLinker* GetClassLinker() = 0;
+  virtual Runtime* GetRuntime() = 0;
+
  private:
   // Chunks must not move their storage after being created - use the node-based std::list.
   std::list<std::vector<uint8_t>> header_code_and_maps_chunks_;
 };
 
+template <typename RuntimeBase>
+class CommonCompilerTestBase : public CommonCompilerTestImpl, public RuntimeBase {
+ public:
+  void SetUp() override {
+    RuntimeBase::SetUp();
+    CommonCompilerTestImpl::SetUp();
+  }
+  void SetUpRuntimeOptions(RuntimeOptions* options) override {
+    RuntimeBase::SetUpRuntimeOptions(options);
+    CommonCompilerTestImpl::SetUpRuntimeOptionsImpl();
+  }
+  void TearDown() override {
+    CommonCompilerTestImpl::TearDown();
+    RuntimeBase::TearDown();
+  }
+
+ protected:
+  ClassLinker* GetClassLinker() override {
+    return RuntimeBase::class_linker_;
+  }
+  Runtime* GetRuntime() override {
+    return RuntimeBase::runtime_.get();
+  }
+};
+
+class CommonCompilerTest : public CommonCompilerTestBase<CommonRuntimeTest> {};
+
+template <typename Param>
+class CommonCompilerTestWithParam
+    : public CommonCompilerTestBase<CommonRuntimeTestWithParam<Param>> {};
+
 }  // namespace art
 
 #endif  // ART_COMPILER_COMMON_COMPILER_TEST_H_