More profiler driven tweaks.

Make more code inlinable by moving to header files.
Use reserve on std::vectors to avoid reallocation.

Change-Id: I1bf67d32dd58ff5c06dec73a247fadc3de593e91
diff --git a/src/base/stringpiece.cc b/src/base/stringpiece.cc
index 715d964..47140e3 100644
--- a/src/base/stringpiece.cc
+++ b/src/base/stringpiece.cc
@@ -21,12 +21,6 @@
 
 namespace art {
 
-bool operator<(const StringPiece& x, const StringPiece& y) {
-  const int r = memcmp(x.data(), y.data(),
-                       std::min(x.size(), y.size()));
-  return ((r < 0) || ((r == 0) && (x.size() < y.size())));
-}
-
 void StringPiece::CopyToString(std::string* target) const {
   target->assign(ptr_, length_);
 }
diff --git a/src/base/stringpiece.h b/src/base/stringpiece.h
index 193f5f7..3664218 100644
--- a/src/base/stringpiece.h
+++ b/src/base/stringpiece.h
@@ -188,7 +188,11 @@
   return !(x == y);
 }
 
-bool operator<(const StringPiece& x, const StringPiece& y);
+inline bool operator<(const StringPiece& x, const StringPiece& y) {
+  const int r = memcmp(x.data(), y.data(),
+                       std::min(x.size(), y.size()));
+  return ((r < 0) || ((r == 0) && (x.size() < y.size())));
+}
 
 inline bool operator>(const StringPiece& x, const StringPiece& y) {
   return y < x;
diff --git a/src/class_linker.cc b/src/class_linker.cc
index cbdcbe0..a66eac6 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -44,7 +44,7 @@
 #include "mirror/class.h"
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
-#include "mirror/dex_cache.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/field-inl.h"
 #include "mirror/iftable-inl.h"
 #include "mirror/abstract_method.h"
diff --git a/src/compiler/dex/mir_dataflow.cc b/src/compiler/dex/mir_dataflow.cc
index f65c9ae..0baf630 100644
--- a/src/compiler/dex/mir_dataflow.cc
+++ b/src/compiler/dex/mir_dataflow.cc
@@ -933,7 +933,7 @@
   SetNumSSARegs(ssa_reg + 1);
   ssa_base_vregs_->Insert(v_reg);
   ssa_subscripts_->Insert(subscript);
-  std::string ssa_name = GetSSAName(ssa_reg);
+  std::string ssa_name(GetSSAName(ssa_reg));
   char* name = static_cast<char*>(arena_->NewMem(ssa_name.length() + 1, false,
                                                  ArenaAllocator::kAllocDFInfo));
   strncpy(name, ssa_name.c_str(), ssa_name.length() + 1);
diff --git a/src/compiler/dex/mir_graph.cc b/src/compiler/dex/mir_graph.cc
index 6154eec..fe0f0c7 100644
--- a/src/compiler/dex/mir_graph.cc
+++ b/src/compiler/dex/mir_graph.cc
@@ -1037,6 +1037,9 @@
 
 std::string MIRGraph::GetSSAName(int ssa_reg)
 {
+  // TODO: This value is needed for LLVM and debugging. Currently, we compute this and then copy to
+  //       the arena. We should be smarter and just place straight into the arena, or compute the
+  //       value more lazily.
   return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg));
 }
 
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index cc65cbe..6feda17 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -34,7 +34,7 @@
 #include "gc/space.h"
 #include "mirror/class_loader.h"
 #include "mirror/class-inl.h"
-#include "mirror/dex_cache.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/field-inl.h"
 #include "mirror/abstract_method-inl.h"
 #include "mirror/object-inl.h"
diff --git a/src/compiler/driver/compiler_driver_test.cc b/src/compiler/driver/compiler_driver_test.cc
index c87fefd..a7fad6f 100644
--- a/src/compiler/driver/compiler_driver_test.cc
+++ b/src/compiler/driver/compiler_driver_test.cc
@@ -26,7 +26,7 @@
 #include "heap.h"
 #include "mirror/class.h"
 #include "mirror/class-inl.h"
-#include "mirror/dex_cache.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/abstract_method-inl.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
diff --git a/src/compiler/llvm/runtime_support_llvm.cc b/src/compiler/llvm/runtime_support_llvm.cc
index bd6b01b..6f2d07a 100644
--- a/src/compiler/llvm/runtime_support_llvm.cc
+++ b/src/compiler/llvm/runtime_support_llvm.cc
@@ -24,6 +24,7 @@
 #include "dex_instruction.h"
 #include "mirror/abstract_method-inl.h"
 #include "mirror/class-inl.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/field-inl.h"
 #include "mirror/object.h"
 #include "mirror/object-inl.h"
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 292e41c..6b69278 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -284,7 +284,8 @@
     if (heap->GetSpaces().size() > 1) {
       ImageSpace* image_space = heap->GetImageSpace();
       image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum();
-      image_file_location_oat_data_begin = reinterpret_cast<uint32_t>(image_space->GetImageHeader().GetOatDataBegin());
+      image_file_location_oat_data_begin =
+          reinterpret_cast<uint32_t>(image_space->GetImageHeader().GetOatDataBegin());
       image_file_location = image_space->GetImageFilename();
       if (host_prefix != NULL && StartsWith(image_file_location, host_prefix->c_str())) {
         image_file_location = image_file_location.substr(host_prefix->size());
@@ -292,6 +293,13 @@
     }
 
     std::vector<uint8_t> oat_contents;
+    // TODO: change ElfWriterQuick to not require the creation of oat_contents. The old pre-mclinker
+    //       OatWriter streamed directly to disk. The new could can be adapted to do it as follows:
+    // 1.) use first pass of OatWriter to calculate size of oat structure,
+    // 2.) call ElfWriterQuick with pointer to OatWriter instead of contents,
+    // 3.) have ElfWriterQuick call back to OatWriter to stream generate the output directly in
+    //     place in the elf file.
+    oat_contents.reserve(5 * MB);
     VectorOutputStream vector_output_stream(oat_file->GetPath(), oat_contents);
     if (!OatWriter::Create(vector_output_stream,
                            dex_files,
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 7e82d6d..bda0138 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -36,7 +36,7 @@
 #include "mirror/array-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/class_loader.h"
-#include "mirror/dex_cache.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/field-inl.h"
 #include "mirror/abstract_method-inl.h"
 #include "mirror/object-inl.h"
diff --git a/src/mirror/dex_cache-inl.h b/src/mirror/dex_cache-inl.h
new file mode 100644
index 0000000..3b17c42
--- /dev/null
+++ b/src/mirror/dex_cache-inl.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_DEX_CACHE_INL_H_
+#define ART_SRC_MIRROR_DEX_CACHE_INL_H_
+
+#include "dex_cache.h"
+
+namespace art {
+namespace mirror {
+
+inline AbstractMethod* DexCache::GetResolvedMethod(uint32_t method_idx) const
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  AbstractMethod* method = GetResolvedMethods()->Get(method_idx);
+  // Hide resolution trampoline methods from the caller
+  if (method != NULL && method->IsRuntimeMethod()) {
+    DCHECK(method == Runtime::Current()->GetResolutionMethod());
+    return NULL;
+  } else {
+    return method;
+  }
+}
+
+}  // namespace mirror
+}  // namespace art
+
+#endif  // ART_SRC_MIRROR_DEX_CACHE_INL_H_
diff --git a/src/mirror/dex_cache.cc b/src/mirror/dex_cache.cc
index 3009786..d9c05fb 100644
--- a/src/mirror/dex_cache.cc
+++ b/src/mirror/dex_cache.cc
@@ -78,17 +78,5 @@
   }
 }
 
-AbstractMethod* DexCache::GetResolvedMethod(uint32_t method_idx) const
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  AbstractMethod* method = GetResolvedMethods()->Get(method_idx);
-  // Hide resolution trampoline methods from the caller
-  if (method != NULL && method->IsRuntimeMethod()) {
-    DCHECK(method == Runtime::Current()->GetResolutionMethod());
-    return NULL;
-  } else {
-    return method;
-  }
-}
-
 }  // namespace mirror
 }  // namespace art
diff --git a/src/oat/runtime/support_invoke.cc b/src/oat/runtime/support_invoke.cc
index a96555d..6a95f3c 100644
--- a/src/oat/runtime/support_invoke.cc
+++ b/src/oat/runtime/support_invoke.cc
@@ -17,6 +17,7 @@
 #include "callee_save_frame.h"
 #include "dex_instruction-inl.h"
 #include "mirror/class-inl.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/abstract_method-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index a7d26bb..674ca12 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -32,11 +32,12 @@
 #include "mirror/abstract_method-inl.h"
 #include "mirror/class.h"
 #include "mirror/class-inl.h"
-#include "mirror/dex_cache.h"
+#include "mirror/dex_cache-inl.h"
 #include "mirror/field-inl.h"
 #include "mirror/object-inl.h"
 #include "mirror/object_array-inl.h"
 #include "object_utils.h"
+#include "register_line-inl.h"
 #include "runtime.h"
 #include "verifier/dex_gc_map.h"
 
@@ -949,9 +950,9 @@
     DCHECK_NE(failures_.size(), 0U);
     return false;  // Not a real failure, but a failure to encode
   }
-#ifndef NDEBUG
-  VerifyGcMap(*map);
-#endif
+  if (kIsDebugBuild) {
+    VerifyGcMap(*map);
+  }
   const std::vector<uint8_t>* dex_gc_map = CreateLengthPrefixedDexGcMap(*(map.get()));
   verifier::MethodVerifier::SetDexGcMap(ref, *dex_gc_map);
 
@@ -3275,6 +3276,7 @@
     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Failed to encode GC map (size=" << table_size << ")";
     return NULL;
   }
+  table->reserve(table_size);
   // Write table header
   table->push_back(format | ((ref_bitmap_bytes >> DexPcToReferenceMap::kRegMapFormatShift) &
                              ~DexPcToReferenceMap::kRegMapFormatMask));
@@ -3335,7 +3337,7 @@
     }
     dex_gc_maps_->Put(ref, &gc_map);
   }
-  CHECK(GetDexGcMap(ref) != NULL);
+  DCHECK(GetDexGcMap(ref) != NULL);
 }
 
 void  MethodVerifier::SetDevirtMap(CompilerDriver::MethodReference ref, const PcToConcreteMethod* devirt_map) {
diff --git a/src/verifier/register_line-inl.h b/src/verifier/register_line-inl.h
new file mode 100644
index 0000000..157e136
--- /dev/null
+++ b/src/verifier/register_line-inl.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_VERIFIER_REGISTER_LINE_INL_H_
+#define ART_SRC_VERIFIER_REGISTER_LINE_INL_H_
+
+#include "register_line.h"
+#include "method_verifier.h"
+
+namespace art {
+namespace verifier {
+
+inline const RegType& RegisterLine::GetRegisterType(uint32_t vsrc) const {
+  // The register index was validated during the static pass, so we don't need to check it here.
+  DCHECK_LT(vsrc, num_regs_);
+  return verifier_->GetRegTypeCache()->GetFromId(line_[vsrc]);
+}
+
+}  // namespace verifier
+}  // namespace art
+
+#endif  // ART_SRC_VERIFIER_REGISTER_LINE_INL_H_
diff --git a/src/verifier/register_line.cc b/src/verifier/register_line.cc
index 544a9ee..31201da 100644
--- a/src/verifier/register_line.cc
+++ b/src/verifier/register_line.cc
@@ -17,6 +17,7 @@
 #include "register_line.h"
 
 #include "method_verifier.h"
+#include "register_line-inl.h"
 
 namespace art {
 namespace verifier {
@@ -92,12 +93,6 @@
   result_[1] = new_type2.GetId();
 }
 
-const RegType& RegisterLine::GetRegisterType(uint32_t vsrc) const {
-  // The register index was validated during the static pass, so we don't need to check it here.
-  DCHECK_LT(vsrc, num_regs_);
-  return verifier_->GetRegTypeCache()->GetFromId(line_[vsrc]);
-}
-
 const RegType& RegisterLine::GetInvocationThis(const DecodedInstruction& dec_insn) {
   if (dec_insn.vA < 1) {
     verifier_->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke lacks 'this'";