Interpreter can kick in even when implicit checks are enabled.

Add a GetStackEndForInterpreter for its stack overfow check.

Change-Id: I2d4fc229a8eb727fda509ff778e16d60d96ecc28
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index e3068b3..47a7f0d 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -397,7 +397,8 @@
 void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver,
                                 uint32_t* args, JValue* result) {
   DCHECK_EQ(self, Thread::Current());
-  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
+  bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
+  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
     ThrowStackOverflowError(self);
     return;
   }
@@ -509,7 +510,8 @@
 JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
                                 ShadowFrame& shadow_frame) {
   DCHECK_EQ(self, Thread::Current());
-  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
+  bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
+  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
     ThrowStackOverflowError(self);
     return JValue();
   }
@@ -520,7 +522,8 @@
 extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh,
                                                   const DexFile::CodeItem* code_item,
                                                   ShadowFrame* shadow_frame, JValue* result) {
-  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
+  bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
+  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
     ThrowStackOverflowError(self);
     return;
   }
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index aca2607..0398365 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -629,8 +629,7 @@
       break;
   }
 
-  if (!options->interpreter_only_ &&
-    (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_)) {
+  if (implicit_null_checks_ || implicit_so_checks_ || implicit_suspend_checks_) {
     fault_manager.Init();
 
     // These need to be in a specific order.  The null point check handler must be
diff --git a/runtime/thread.h b/runtime/thread.h
index c555034..998f7db 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -550,6 +550,16 @@
     return tlsPtr_.stack_size - (tlsPtr_.stack_end - tlsPtr_.stack_begin);
   }
 
+  byte* GetStackEndForInterpreter(bool implicit_overflow_check) const {
+    if (implicit_overflow_check) {
+      // The interpreter needs the extra overflow bytes that stack_end does
+      // not include.
+      return tlsPtr_.stack_end + GetStackOverflowReservedBytes(kRuntimeISA);
+    } else {
+      return tlsPtr_.stack_end;
+    }
+  }
+
   byte* GetStackEnd() const {
     return tlsPtr_.stack_end;
   }