Refactor runtime support.

Change-Id: Id7470a4105838150d5ceb73ab2c8c83e739660df
diff --git a/src/oat/utils/assembler.cc b/src/oat/utils/assembler.cc
new file mode 100644
index 0000000..249a771
--- /dev/null
+++ b/src/oat/utils/assembler.cc
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "assembler.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "arm/assembler_arm.h"
+#include "x86/assembler_x86.h"
+#include "globals.h"
+#include "memory_region.h"
+
+namespace art {
+
+static byte* NewContents(size_t capacity) {
+  return new byte[capacity];
+}
+
+
+AssemblerBuffer::AssemblerBuffer() {
+  static const size_t kInitialBufferCapacity = 4 * KB;
+  contents_ = NewContents(kInitialBufferCapacity);
+  cursor_ = contents_;
+  limit_ = ComputeLimit(contents_, kInitialBufferCapacity);
+  fixup_ = NULL;
+  slow_path_ = NULL;
+#ifndef NDEBUG
+  has_ensured_capacity_ = false;
+  fixups_processed_ = false;
+#endif
+
+  // Verify internal state.
+  CHECK_EQ(Capacity(), kInitialBufferCapacity);
+  CHECK_EQ(Size(), 0U);
+}
+
+
+AssemblerBuffer::~AssemblerBuffer() {
+  delete[] contents_;
+}
+
+
+void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) {
+  AssemblerFixup* fixup = fixup_;
+  while (fixup != NULL) {
+    fixup->Process(region, fixup->position());
+    fixup = fixup->previous();
+  }
+}
+
+
+void AssemblerBuffer::FinalizeInstructions(const MemoryRegion& instructions) {
+  // Copy the instructions from the buffer.
+  MemoryRegion from(reinterpret_cast<void*>(contents()), Size());
+  instructions.CopyFrom(0, from);
+  // Process fixups in the instructions.
+  ProcessFixups(instructions);
+#ifndef NDEBUG
+  fixups_processed_ = true;
+#endif
+}
+
+
+void AssemblerBuffer::ExtendCapacity() {
+  size_t old_size = Size();
+  size_t old_capacity = Capacity();
+  size_t new_capacity = std::min(old_capacity * 2, old_capacity + 1 * MB);
+
+  // Allocate the new data area and copy contents of the old one to it.
+  byte* new_contents = NewContents(new_capacity);
+  memmove(reinterpret_cast<void*>(new_contents),
+          reinterpret_cast<void*>(contents_),
+          old_size);
+
+  // Compute the relocation delta and switch to the new contents area.
+  ptrdiff_t delta = new_contents - contents_;
+  contents_ = new_contents;
+
+  // Update the cursor and recompute the limit.
+  cursor_ += delta;
+  limit_ = ComputeLimit(new_contents, new_capacity);
+
+  // Verify internal state.
+  CHECK_EQ(Capacity(), new_capacity);
+  CHECK_EQ(Size(), old_size);
+}
+
+
+Assembler* Assembler::Create(InstructionSet instruction_set) {
+  if (instruction_set == kX86) {
+    return new x86::X86Assembler();
+  } else {
+    CHECK(instruction_set == kArm || instruction_set == kThumb2);
+    return new arm::ArmAssembler();
+  }
+}
+
+}  // namespace art