Allocate LSEVisitor on the arena stack.

Use a simple wrapper to allocate the LSEVisitor on the arena
stack. This allows adding additional members to the class
without running into stack frame size errors with clang.

Make the pre-allocated buffer for `store_records_` a member
of LSEVisitor as originally intended.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 181943478
Change-Id: I88b8ca5f9c765cc26e884e9f29cb2c870c799e13
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index 7495601..b1ec62a 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -1251,6 +1251,7 @@
   };
   // Small pre-allocated initial buffer avoids initializing a large one until it's really needed.
   static constexpr size_t kStoreRecordsInitialBufferSize = 16;
+  std::pair<HInstruction*, StoreRecord> store_records_buffer_[kStoreRecordsInitialBufferSize];
   ScopedArenaHashMap<HInstruction*, StoreRecord> store_records_;
 
   // Replacements for Phi placeholders.
@@ -1441,8 +1442,7 @@
                                                   /*expandable=*/false,
                                                   kArenaAllocLSE),
       loads_requiring_loop_phi_(allocator_.Adapter(kArenaAllocLSE)),
-      store_records_(allocator_.AllocArray<std::pair<HInstruction*, StoreRecord>>(
-                         kStoreRecordsInitialBufferSize, kArenaAllocLSE),
+      store_records_(store_records_buffer_,
                      kStoreRecordsInitialBufferSize,
                      allocator_.Adapter(kArenaAllocLSE)),
       phi_placeholder_replacements_(num_phi_placeholders_,
@@ -3763,6 +3763,24 @@
   }
 }
 
+// The LSEVisitor is a ValueObject (indirectly through base classes) and therefore
+// cannot be directly allocated with an arena allocator, so we need to wrap it.
+class LSEVisitorWrapper : public DeletableArenaObject<kArenaAllocLSE> {
+ public:
+  LSEVisitorWrapper(HGraph* graph,
+                    const HeapLocationCollector& heap_location_collector,
+                    bool perform_partial_lse,
+                    OptimizingCompilerStats* stats)
+      : lse_visitor_(graph, heap_location_collector, perform_partial_lse, stats) {}
+
+  void Run() {
+    lse_visitor_.Run();
+  }
+
+ private:
+  LSEVisitor lse_visitor_;
+};
+
 bool LoadStoreElimination::Run(bool enable_partial_lse) {
   if (graph_->IsDebuggable() || graph_->HasTryCatch()) {
     // Debugger may set heap values or trigger deoptimization of callers.
@@ -3789,8 +3807,9 @@
     return false;
   }
 
-  LSEVisitor lse_visitor(graph_, heap_location_collector, enable_partial_lse, stats_);
-  lse_visitor.Run();
+  std::unique_ptr<LSEVisitorWrapper> lse_visitor(new (&allocator) LSEVisitorWrapper(
+      graph_, heap_location_collector, enable_partial_lse, stats_));
+  lse_visitor->Run();
   return true;
 }