Revert "Revert "Introduce support for hardware simulators, starting with ARM64""

This reverts commit 4cd27d64b0bbdde61fa3f6674ceb24221853ac2c.

This depends on VIXL 1.11.

Change-Id: I402c1fd6bbb218ba80ef8e59af203c9276151059
diff --git a/runtime/Android.mk b/runtime/Android.mk
index 1fdffe3..5211762 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -41,6 +41,7 @@
   check_jni.cc \
   class_linker.cc \
   class_table.cc \
+  code_simulator_container.cc \
   common_throws.cc \
   debugger.cc \
   dex_file.cc \
diff --git a/runtime/base/logging.h b/runtime/base/logging.h
index 2cd1a4d..115c260 100644
--- a/runtime/base/logging.h
+++ b/runtime/base/logging.h
@@ -48,6 +48,7 @@
   bool oat;
   bool profiler;
   bool signals;
+  bool simulator;
   bool startup;
   bool third_party_jni;  // Enabled with "-verbose:third-party-jni".
   bool threads;
diff --git a/runtime/code_simulator_container.cc b/runtime/code_simulator_container.cc
new file mode 100644
index 0000000..d884c58
--- /dev/null
+++ b/runtime/code_simulator_container.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 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 <dlfcn.h>
+
+#include "code_simulator_container.h"
+#include "globals.h"
+
+namespace art {
+
+CodeSimulatorContainer::CodeSimulatorContainer(InstructionSet target_isa)
+    : libart_simulator_handle_(nullptr),
+      simulator_(nullptr) {
+  const char* libart_simulator_so_name =
+      kIsDebugBuild ? "libartd-simulator.so" : "libart-simulator.so";
+  libart_simulator_handle_ = dlopen(libart_simulator_so_name, RTLD_NOW);
+  // It is not a real error when libart-simulator does not exist, e.g., on target.
+  if (libart_simulator_handle_ == nullptr) {
+    VLOG(simulator) << "Could not load " << libart_simulator_so_name << ": " << dlerror();
+  } else {
+    typedef CodeSimulator* (*create_code_simulator_ptr_)(InstructionSet target_isa);
+    create_code_simulator_ptr_ create_code_simulator_ =
+        reinterpret_cast<create_code_simulator_ptr_>(
+            dlsym(libart_simulator_handle_, "CreateCodeSimulator"));
+    DCHECK(create_code_simulator_ != nullptr) << "Fail to find symbol of CreateCodeSimulator: "
+        << dlerror();
+    simulator_ = create_code_simulator_(target_isa);
+  }
+}
+
+CodeSimulatorContainer::~CodeSimulatorContainer() {
+  // Free simulator object before closing libart-simulator because destructor of
+  // CodeSimulator lives in it.
+  if (simulator_ != nullptr) {
+    delete simulator_;
+  }
+  if (libart_simulator_handle_ != nullptr) {
+    dlclose(libart_simulator_handle_);
+  }
+}
+
+}  // namespace art
diff --git a/runtime/code_simulator_container.h b/runtime/code_simulator_container.h
new file mode 100644
index 0000000..655a247
--- /dev/null
+++ b/runtime/code_simulator_container.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 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_RUNTIME_CODE_SIMULATOR_CONTAINER_H_
+#define ART_RUNTIME_CODE_SIMULATOR_CONTAINER_H_
+
+#include "arch/instruction_set.h"
+#include "simulator/code_simulator.h"
+
+namespace art {
+
+// This container dynamically opens and closes libart-simulator.
+class CodeSimulatorContainer {
+ public:
+  explicit CodeSimulatorContainer(InstructionSet target_isa);
+  ~CodeSimulatorContainer();
+
+  bool CanSimulate() const {
+    return simulator_ != nullptr;
+  }
+
+  CodeSimulator* Get() {
+    DCHECK(CanSimulate());
+    return simulator_;
+  }
+
+  const CodeSimulator* Get() const {
+    DCHECK(CanSimulate());
+    return simulator_;
+  }
+
+ private:
+  void* libart_simulator_handle_;
+  CodeSimulator* simulator_;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeSimulatorContainer);
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_CODE_SIMULATOR_CONTAINER_H_
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index ae16c7f..fbb7de8 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -395,6 +395,7 @@
   //  gLogVerbosity.oat = true;  // TODO: don't check this in!
   //  gLogVerbosity.profiler = true;  // TODO: don't check this in!
   //  gLogVerbosity.signals = true;  // TODO: don't check this in!
+  //  gLogVerbosity.simulator = true; // TODO: don't check this in!
   //  gLogVerbosity.startup = true;  // TODO: don't check this in!
   //  gLogVerbosity.third_party_jni = true;  // TODO: don't check this in!
   //  gLogVerbosity.threads = true;  // TODO: don't check this in!
diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc
index a8575de..8289ef1 100644
--- a/runtime/parsed_options_test.cc
+++ b/runtime/parsed_options_test.cc
@@ -87,6 +87,8 @@
   EXPECT_FALSE(VLOG_IS_ON(jdwp));
   EXPECT_TRUE(VLOG_IS_ON(jni));
   EXPECT_FALSE(VLOG_IS_ON(monitor));
+  EXPECT_FALSE(VLOG_IS_ON(signals));
+  EXPECT_FALSE(VLOG_IS_ON(simulator));
   EXPECT_FALSE(VLOG_IS_ON(startup));
   EXPECT_FALSE(VLOG_IS_ON(third_party_jni));
   EXPECT_FALSE(VLOG_IS_ON(threads));
diff --git a/runtime/simulator/Android.mk b/runtime/simulator/Android.mk
new file mode 100644
index 0000000..c154eb6
--- /dev/null
+++ b/runtime/simulator/Android.mk
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include art/build/Android.common_build.mk
+
+LIBART_SIMULATOR_SRC_FILES := \
+  code_simulator.cc \
+  code_simulator_arm64.cc
+
+# $(1): target or host
+# $(2): ndebug or debug
+define build-libart-simulator
+  ifneq ($(1),target)
+    ifneq ($(1),host)
+      $$(error expected target or host for argument 1, received $(1))
+    endif
+  endif
+  ifneq ($(2),ndebug)
+    ifneq ($(2),debug)
+      $$(error expected ndebug or debug for argument 2, received $(2))
+    endif
+  endif
+
+  art_target_or_host := $(1)
+  art_ndebug_or_debug := $(2)
+
+  include $(CLEAR_VARS)
+  ifeq ($$(art_target_or_host),host)
+     LOCAL_IS_HOST_MODULE := true
+  endif
+  LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
+  ifeq ($$(art_ndebug_or_debug),ndebug)
+    LOCAL_MODULE := libart-simulator
+  else # debug
+    LOCAL_MODULE := libartd-simulator
+  endif
+
+  LOCAL_MODULE_TAGS := optional
+  LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+  LOCAL_SRC_FILES := $$(LIBART_SIMULATOR_SRC_FILES)
+
+  ifeq ($$(art_target_or_host),target)
+    $(call set-target-local-clang-vars)
+    $(call set-target-local-cflags-vars,$(2))
+  else # host
+    LOCAL_CLANG := $(ART_HOST_CLANG)
+    LOCAL_LDLIBS := $(ART_HOST_LDLIBS)
+    LOCAL_CFLAGS += $(ART_HOST_CFLAGS)
+    LOCAL_ASFLAGS += $(ART_HOST_ASFLAGS)
+    ifeq ($$(art_ndebug_or_debug),debug)
+      LOCAL_CFLAGS += $(ART_HOST_DEBUG_CFLAGS)
+    else
+      LOCAL_CFLAGS += $(ART_HOST_NON_DEBUG_CFLAGS)
+    endif
+  endif
+
+  LOCAL_SHARED_LIBRARIES += liblog
+  ifeq ($$(art_ndebug_or_debug),debug)
+    LOCAL_SHARED_LIBRARIES += libartd
+  else
+    LOCAL_SHARED_LIBRARIES += libart
+  endif
+
+  LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime
+  LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+  LOCAL_MULTILIB := both
+
+  LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+  LOCAL_NATIVE_COVERAGE := $(ART_COVERAGE)
+  # For simulator_arm64.
+  ifeq ($$(art_ndebug_or_debug),debug)
+     LOCAL_SHARED_LIBRARIES += libvixld
+  else
+     LOCAL_SHARED_LIBRARIES += libvixl
+  endif
+  ifeq ($$(art_target_or_host),target)
+    include $(BUILD_SHARED_LIBRARY)
+  else # host
+    include $(BUILD_HOST_SHARED_LIBRARY)
+  endif
+endef
+
+ifeq ($(ART_BUILD_HOST_NDEBUG),true)
+  $(eval $(call build-libart-simulator,host,ndebug))
+endif
+ifeq ($(ART_BUILD_HOST_DEBUG),true)
+  $(eval $(call build-libart-simulator,host,debug))
+endif
diff --git a/runtime/simulator/code_simulator.cc b/runtime/simulator/code_simulator.cc
new file mode 100644
index 0000000..1a11160
--- /dev/null
+++ b/runtime/simulator/code_simulator.cc
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 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 "simulator/code_simulator.h"
+#include "simulator/code_simulator_arm64.h"
+
+namespace art {
+
+CodeSimulator* CodeSimulator::CreateCodeSimulator(InstructionSet target_isa) {
+  switch (target_isa) {
+    case kArm64:
+      return arm64::CodeSimulatorArm64::CreateCodeSimulatorArm64();
+    default:
+      return nullptr;
+  }
+}
+
+CodeSimulator* CreateCodeSimulator(InstructionSet target_isa) {
+  return CodeSimulator::CreateCodeSimulator(target_isa);
+}
+
+}  // namespace art
diff --git a/runtime/simulator/code_simulator.h b/runtime/simulator/code_simulator.h
new file mode 100644
index 0000000..bd48909
--- /dev/null
+++ b/runtime/simulator/code_simulator.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 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_RUNTIME_SIMULATOR_CODE_SIMULATOR_H_
+#define ART_RUNTIME_SIMULATOR_CODE_SIMULATOR_H_
+
+#include "arch/instruction_set.h"
+
+namespace art {
+
+class CodeSimulator {
+ public:
+  CodeSimulator() {}
+  virtual ~CodeSimulator() {}
+  // Returns a null pointer if a simulator cannot be found for target_isa.
+  static CodeSimulator* CreateCodeSimulator(InstructionSet target_isa);
+
+  virtual void RunFrom(intptr_t code_buffer) = 0;
+
+  // Get return value according to C ABI.
+  virtual bool GetCReturnBool() const = 0;
+  virtual int32_t GetCReturnInt32() const = 0;
+  virtual int64_t GetCReturnInt64() const = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CodeSimulator);
+};
+
+extern "C" CodeSimulator* CreateCodeSimulator(InstructionSet target_isa);
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_SIMULATOR_CODE_SIMULATOR_H_
diff --git a/runtime/simulator/code_simulator_arm64.cc b/runtime/simulator/code_simulator_arm64.cc
new file mode 100644
index 0000000..39dfa6d
--- /dev/null
+++ b/runtime/simulator/code_simulator_arm64.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 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 "simulator/code_simulator_arm64.h"
+
+namespace art {
+namespace arm64 {
+
+// VIXL has not been tested on 32bit architectures, so vixl::Simulator is not always
+// available. To avoid linker error on these architectures, we check if we can simulate
+// in the beginning of following methods, with compile time constant `kCanSimulate`.
+// TODO: when vixl::Simulator is always available, remove the these checks.
+
+CodeSimulatorArm64* CodeSimulatorArm64::CreateCodeSimulatorArm64() {
+  if (kCanSimulate) {
+    return new CodeSimulatorArm64();
+  } else {
+    return nullptr;
+  }
+}
+
+CodeSimulatorArm64::CodeSimulatorArm64()
+    : CodeSimulator(), decoder_(nullptr), simulator_(nullptr) {
+  DCHECK(kCanSimulate);
+  decoder_ = new vixl::Decoder();
+  simulator_ = new vixl::Simulator(decoder_);
+}
+
+CodeSimulatorArm64::~CodeSimulatorArm64() {
+  DCHECK(kCanSimulate);
+  delete simulator_;
+  delete decoder_;
+}
+
+void CodeSimulatorArm64::RunFrom(intptr_t code_buffer) {
+  DCHECK(kCanSimulate);
+  simulator_->RunFrom(reinterpret_cast<const vixl::Instruction*>(code_buffer));
+}
+
+bool CodeSimulatorArm64::GetCReturnBool() const {
+  DCHECK(kCanSimulate);
+  return simulator_->wreg(0);
+}
+
+int32_t CodeSimulatorArm64::GetCReturnInt32() const {
+  DCHECK(kCanSimulate);
+  return simulator_->wreg(0);
+}
+
+int64_t CodeSimulatorArm64::GetCReturnInt64() const {
+  DCHECK(kCanSimulate);
+  return simulator_->xreg(0);
+}
+
+}  // namespace arm64
+}  // namespace art
diff --git a/runtime/simulator/code_simulator_arm64.h b/runtime/simulator/code_simulator_arm64.h
new file mode 100644
index 0000000..10fceb9
--- /dev/null
+++ b/runtime/simulator/code_simulator_arm64.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 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_RUNTIME_SIMULATOR_CODE_SIMULATOR_ARM64_H_
+#define ART_RUNTIME_SIMULATOR_CODE_SIMULATOR_ARM64_H_
+
+#include "memory"
+#include "simulator/code_simulator.h"
+// TODO: make vixl clean wrt -Wshadow.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include "vixl/a64/simulator-a64.h"
+#pragma GCC diagnostic pop
+
+namespace art {
+namespace arm64 {
+
+class CodeSimulatorArm64 : public CodeSimulator {
+ public:
+  static CodeSimulatorArm64* CreateCodeSimulatorArm64();
+  virtual ~CodeSimulatorArm64();
+
+  void RunFrom(intptr_t code_buffer) OVERRIDE;
+
+  bool GetCReturnBool() const OVERRIDE;
+  int32_t GetCReturnInt32() const OVERRIDE;
+  int64_t GetCReturnInt64() const OVERRIDE;
+
+ private:
+  CodeSimulatorArm64();
+
+  vixl::Decoder* decoder_;
+  vixl::Simulator* simulator_;
+
+  // TODO: Enable CodeSimulatorArm64 for more host ISAs once vixl::Simulator supports them.
+  static constexpr bool kCanSimulate = (kRuntimeISA == kX86_64);
+
+  DISALLOW_COPY_AND_ASSIGN(CodeSimulatorArm64);
+};
+
+}  // namespace arm64
+}  // namespace art
+
+#endif  // ART_RUNTIME_SIMULATOR_CODE_SIMULATOR_ARM64_H_