Revert "Revert "Add JIT""

Added missing EntryPointToCodePointer.

This reverts commit a5ca888d715cd0c6c421313211caa1928be3e399.

Change-Id: Ia74df0ef3a7babbdcb0466fd24da28e304e3f5af
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
new file mode 100644
index 0000000..8d4965e
--- /dev/null
+++ b/runtime/jit/jit_code_cache.cc
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2014 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 "jit_code_cache.h"
+
+#include <sstream>
+
+#include "mem_map.h"
+#include "mirror/art_method-inl.h"
+#include "oat_file-inl.h"
+
+namespace art {
+namespace jit {
+
+JitCodeCache* JitCodeCache::Create(size_t capacity, std::string* error_msg) {
+  CHECK_GT(capacity, 0U);
+  CHECK_LT(capacity, kMaxCapacity);
+  std::string error_str;
+  // Map name specific for android_os_Debug.cpp accounting.
+  MemMap* map = MemMap::MapAnonymous("jit-code-cache", nullptr, capacity,
+                                     PROT_READ | PROT_WRITE | PROT_EXEC, false, &error_str);
+  if (map == nullptr) {
+    std::ostringstream oss;
+    oss << "Failed to create read write execute cache: " << error_str << " size=" << capacity;
+    *error_msg = oss.str();
+    return nullptr;
+  }
+  return new JitCodeCache(map);
+}
+
+JitCodeCache::JitCodeCache(MemMap* mem_map)
+    : lock_("Jit code cache", kJitCodeCacheLock), num_methods_(0) {
+  VLOG(jit) << "Created jit code cache size=" << PrettySize(mem_map->Size());
+  mem_map_.reset(mem_map);
+  uint8_t* divider = mem_map->Begin() + RoundUp(mem_map->Size() / 4, kPageSize);
+  // Data cache is 1 / 4 of the map. TODO: Make this variable?
+  // Put data at the start.
+  data_cache_ptr_ = mem_map->Begin();
+  data_cache_end_ = divider;
+  data_cache_begin_ = data_cache_ptr_;
+  mprotect(data_cache_ptr_, data_cache_end_ - data_cache_begin_, PROT_READ | PROT_WRITE);
+  // Code cache after.
+  code_cache_begin_ = divider;
+  code_cache_ptr_ = divider;
+  code_cache_end_ = mem_map->End();
+}
+
+bool JitCodeCache::ContainsMethod(mirror::ArtMethod* method) const {
+  return ContainsCodePtr(method->GetEntryPointFromQuickCompiledCode());
+}
+
+bool JitCodeCache::ContainsCodePtr(const void* ptr) const {
+  return ptr >= code_cache_begin_ && ptr < code_cache_end_;
+}
+
+void JitCodeCache::FlushInstructionCache() {
+  UNIMPLEMENTED(FATAL);
+  // TODO: Investigate if we need to do this.
+  // __clear_cache(reinterpret_cast<char*>(code_cache_begin_), static_cast<int>(CodeCacheSize()));
+}
+
+uint8_t* JitCodeCache::ReserveCode(Thread* self, size_t size) {
+  MutexLock mu(self, lock_);
+  if (size > CodeCacheRemain()) {
+    return nullptr;
+  }
+  code_cache_ptr_ += size;
+  return code_cache_ptr_ - size;
+}
+
+uint8_t* JitCodeCache::AddDataArray(Thread* self, const uint8_t* begin, const uint8_t* end) {
+  MutexLock mu(self, lock_);
+  const size_t size = end - begin;
+  if (size > DataCacheRemain()) {
+    return nullptr;  // Out of space in the data cache.
+  }
+  std::copy(begin, end, data_cache_ptr_);
+  data_cache_ptr_ += size;
+  return data_cache_ptr_ - size;
+}
+
+const void* JitCodeCache::GetCodeFor(mirror::ArtMethod* method) {
+  const void* code = method->GetEntryPointFromQuickCompiledCode();
+  if (ContainsCodePtr(code)) {
+    return code;
+  }
+  MutexLock mu(Thread::Current(), lock_);
+  auto it = method_code_map_.find(method);
+  if (it != method_code_map_.end()) {
+    return it->second;
+  }
+  return nullptr;
+}
+
+void JitCodeCache::SaveCompiledCode(mirror::ArtMethod* method, const void* old_code_ptr) {
+  DCHECK_EQ(method->GetEntryPointFromQuickCompiledCode(), old_code_ptr);
+  DCHECK(ContainsCodePtr(old_code_ptr)) << PrettyMethod(method) << " old_code_ptr="
+      << old_code_ptr;
+  MutexLock mu(Thread::Current(), lock_);
+  auto it = method_code_map_.find(method);
+  if (it != method_code_map_.end()) {
+    return;
+  }
+  method_code_map_.Put(method, old_code_ptr);
+}
+
+}  // namespace jit
+}  // namespace art