Another workaround for stack overflow issue with clang

Bug: 14882674
Change-Id: I465fda533714021b39b847afe89e454758646b47
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index cfc90a6..b8c2286 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -84,6 +84,17 @@
                               const DexFile::CodeItem* code_item,
                               ShadowFrame& shadow_frame, JValue result_register);
 
+// Workaround for b/14882674 where clang allocates stack for each ThrowLocation created by calls to
+// ShadowFrame::GetCurrentLocationForThrow(). Moving the call here prevents from doing such
+// allocation in the interpreter itself.
+static inline void ThrowNullPointerExceptionFromInterpreter(const ShadowFrame& shadow_frame)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) SOMETIMES_INLINE;
+
+static inline void ThrowNullPointerExceptionFromInterpreter(
+    const ShadowFrame& shadow_frame) {
+  ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+}
+
 static inline void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
   ref->MonitorEnter(self);
 }
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 9a274f6..99153c8 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -462,7 +462,7 @@
   HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
     Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
     if (UNLIKELY(obj == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       DoMonitorEnter(self, obj);
@@ -474,7 +474,7 @@
   HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
     Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
     if (UNLIKELY(obj == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       DoMonitorExit(self, obj);
@@ -516,7 +516,7 @@
   HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
     Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
     if (UNLIKELY(array == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
@@ -957,7 +957,7 @@
   HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -975,7 +975,7 @@
   HANDLE_INSTRUCTION_START(AGET_BYTE) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -993,7 +993,7 @@
   HANDLE_INSTRUCTION_START(AGET_CHAR) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -1011,7 +1011,7 @@
   HANDLE_INSTRUCTION_START(AGET_SHORT) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -1029,7 +1029,7 @@
   HANDLE_INSTRUCTION_START(AGET) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -1047,7 +1047,7 @@
   HANDLE_INSTRUCTION_START(AGET_WIDE)  {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -1065,7 +1065,7 @@
   HANDLE_INSTRUCTION_START(AGET_OBJECT) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
@@ -1083,7 +1083,7 @@
   HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
@@ -1102,7 +1102,7 @@
   HANDLE_INSTRUCTION_START(APUT_BYTE) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
@@ -1121,7 +1121,7 @@
   HANDLE_INSTRUCTION_START(APUT_CHAR) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
@@ -1140,7 +1140,7 @@
   HANDLE_INSTRUCTION_START(APUT_SHORT) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
@@ -1159,7 +1159,7 @@
   HANDLE_INSTRUCTION_START(APUT) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
@@ -1178,7 +1178,7 @@
   HANDLE_INSTRUCTION_START(APUT_WIDE) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
@@ -1197,7 +1197,7 @@
   HANDLE_INSTRUCTION_START(APUT_OBJECT) {
     Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
     if (UNLIKELY(a == NULL)) {
-      ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+      ThrowNullPointerExceptionFromInterpreter(shadow_frame);
       HANDLE_PENDING_EXCEPTION();
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 68759ad..5e4f5be 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -375,7 +375,7 @@
         PREAMBLE();
         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
         if (UNLIKELY(obj == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
         } else {
           DoMonitorEnter(self, obj);
@@ -387,7 +387,7 @@
         PREAMBLE();
         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
         if (UNLIKELY(obj == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
         } else {
           DoMonitorExit(self, obj);
@@ -429,7 +429,7 @@
         PREAMBLE();
         Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
         if (UNLIKELY(array == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
         } else {
           shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
@@ -855,7 +855,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -873,7 +873,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -891,7 +891,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -909,7 +909,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -927,7 +927,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -945,7 +945,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -963,7 +963,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -981,7 +981,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -1000,7 +1000,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -1019,7 +1019,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -1038,7 +1038,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -1057,7 +1057,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -1076,7 +1076,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }
@@ -1095,7 +1095,7 @@
         PREAMBLE();
         Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
         if (UNLIKELY(a == NULL)) {
-          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          ThrowNullPointerExceptionFromInterpreter(shadow_frame);
           HANDLE_PENDING_EXCEPTION();
           break;
         }