[libunwind] Improve unwinder stack usage - III

Implement the same optimization committed under r271004 on non-EHABI,
non-SJLJ unwinder as well.

Change-Id: I7f80ed91a75d1e778b50ba87cf8fb68658a083c7

git-svn-id: https://llvm.org/svn/llvm-project/libunwind/trunk@272680 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/src/UnwindLevel1.c b/src/UnwindLevel1.c
index ce6eb28..7294f25 100644
--- a/src/UnwindLevel1.c
+++ b/src/UnwindLevel1.c
@@ -33,16 +33,15 @@
 #if !_LIBUNWIND_ARM_EHABI
 
 static _Unwind_Reason_Code
-unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
-  unw_cursor_t cursor1;
-  unw_init_local(&cursor1, uc);
+unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
+  unw_init_local(cursor, uc);
 
   // Walk each frame looking for a place to stop.
   bool handlerNotFound = true;
   while (handlerNotFound) {
     // Ask libuwind to get next frame (skip over first which is
     // _Unwind_RaiseException).
-    int stepResult = unw_step(&cursor1);
+    int stepResult = unw_step(cursor);
     if (stepResult == 0) {
       _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
                                  "bottom => _URC_END_OF_STACK\n",
@@ -58,7 +57,7 @@
     // See if frame has code to run (has personality routine).
     unw_proc_info_t frameInfo;
     unw_word_t sp;
-    if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
+    if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
       _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
                                  "failed => _URC_FATAL_PHASE1_ERROR\n",
                                  (void *)exception_object);
@@ -70,12 +69,12 @@
       char functionBuf[512];
       const char *functionName = functionBuf;
       unw_word_t offset;
-      if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
+      if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
                              &offset) != UNW_ESUCCESS) ||
           (frameInfo.start_ip + offset > frameInfo.end_ip))
         functionName = ".anonymous.";
       unw_word_t pc;
-      unw_get_reg(&cursor1, UNW_REG_IP, &pc);
+      unw_get_reg(cursor, UNW_REG_IP, &pc);
       _LIBUNWIND_TRACE_UNWINDING(
           "unwind_phase1(ex_ojb=%p): pc=0x%" PRIx64 ", start_ip=0x%" PRIx64
           ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
@@ -93,13 +92,13 @@
           (void *)exception_object, (void *)(uintptr_t)p);
       _Unwind_Reason_Code personalityResult =
           (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
-               exception_object, (struct _Unwind_Context *)(&cursor1));
+               exception_object, (struct _Unwind_Context *)(cursor));
       switch (personalityResult) {
       case _URC_HANDLER_FOUND:
         // found a catch clause or locals that need destructing in this frame
         // stop search and remember stack pointer at the frame
         handlerNotFound = false;
-        unw_get_reg(&cursor1, UNW_REG_SP, &sp);
+        unw_get_reg(cursor, UNW_REG_SP, &sp);
         exception_object->private_2 = (uintptr_t)sp;
         _LIBUNWIND_TRACE_UNWINDING(
             "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
@@ -127,9 +126,8 @@
 
 
 static _Unwind_Reason_Code
-unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
-  unw_cursor_t cursor2;
-  unw_init_local(&cursor2, uc);
+unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
+  unw_init_local(cursor, uc);
 
   _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
                              (void *)exception_object);
@@ -139,7 +137,7 @@
 
     // Ask libuwind to get next frame (skip over first which is
     // _Unwind_RaiseException).
-    int stepResult = unw_step(&cursor2);
+    int stepResult = unw_step(cursor);
     if (stepResult == 0) {
       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
                                  "bottom => _URC_END_OF_STACK\n",
@@ -155,8 +153,8 @@
     // Get info about this frame.
     unw_word_t sp;
     unw_proc_info_t frameInfo;
-    unw_get_reg(&cursor2, UNW_REG_SP, &sp);
-    if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
+    unw_get_reg(cursor, UNW_REG_SP, &sp);
+    if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
                                  "failed => _URC_FATAL_PHASE1_ERROR\n",
                                  (void *)exception_object);
@@ -168,7 +166,7 @@
       char functionBuf[512];
       const char *functionName = functionBuf;
       unw_word_t offset;
-      if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+      if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
                              &offset) != UNW_ESUCCESS) ||
           (frameInfo.start_ip + offset > frameInfo.end_ip))
         functionName = ".anonymous.";
@@ -191,7 +189,7 @@
       }
        _Unwind_Reason_Code personalityResult =
           (*p)(1, action, exception_object->exception_class, exception_object,
-               (struct _Unwind_Context *)(&cursor2));
+               (struct _Unwind_Context *)(cursor));
       switch (personalityResult) {
       case _URC_CONTINUE_UNWIND:
         // Continue unwinding
@@ -212,14 +210,14 @@
         // We may get control back if landing pad calls _Unwind_Resume().
         if (_LIBUNWIND_TRACING_UNWINDING) {
           unw_word_t pc;
-          unw_get_reg(&cursor2, UNW_REG_IP, &pc);
-          unw_get_reg(&cursor2, UNW_REG_SP, &sp);
+          unw_get_reg(cursor, UNW_REG_IP, &pc);
+          unw_get_reg(cursor, UNW_REG_SP, &sp);
           _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
                                      "user code with ip=0x%" PRIx64
                                      ", sp=0x%" PRIx64 "\n",
                                      (void *)exception_object, pc, sp);
         }
-        unw_resume(&cursor2);
+        unw_resume(cursor);
         // unw_resume() only returns if there was an error.
         return _URC_FATAL_PHASE2_ERROR;
       default:
@@ -237,18 +235,17 @@
 }
 
 static _Unwind_Reason_Code
-unwind_phase2_forced(unw_context_t *uc,
+unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
                      _Unwind_Exception *exception_object,
                      _Unwind_Stop_Fn stop, void *stop_parameter) {
-  unw_cursor_t cursor2;
-  unw_init_local(&cursor2, uc);
+  unw_init_local(cursor, uc);
 
   // Walk each frame until we reach where search phase said to stop
-  while (unw_step(&cursor2) > 0) {
+  while (unw_step(cursor) > 0) {
 
     // Update info about this frame.
     unw_proc_info_t frameInfo;
-    if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
+    if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
       _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
                                  "failed => _URC_END_OF_STACK\n",
                                  (void *)exception_object);
@@ -260,7 +257,7 @@
       char functionBuf[512];
       const char *functionName = functionBuf;
       unw_word_t offset;
-      if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+      if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf),
                              &offset) != UNW_ESUCCESS) ||
           (frameInfo.start_ip + offset > frameInfo.end_ip))
         functionName = ".anonymous.";
@@ -276,7 +273,7 @@
         (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE);
     _Unwind_Reason_Code stopResult =
         (*stop)(1, action, exception_object->exception_class, exception_object,
-                (struct _Unwind_Context *)(&cursor2), stop_parameter);
+                (struct _Unwind_Context *)(cursor), stop_parameter);
     _LIBUNWIND_TRACE_UNWINDING(
         "unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
         (void *)exception_object, stopResult);
@@ -296,7 +293,7 @@
           (void *)exception_object, (void *)(uintptr_t)p);
       _Unwind_Reason_Code personalityResult =
           (*p)(1, action, exception_object->exception_class, exception_object,
-               (struct _Unwind_Context *)(&cursor2));
+               (struct _Unwind_Context *)(cursor));
       switch (personalityResult) {
       case _URC_CONTINUE_UNWIND:
         _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
@@ -311,7 +308,7 @@
                                    "_URC_INSTALL_CONTEXT\n",
                                    (void *)exception_object);
         // We may get control back if landing pad calls _Unwind_Resume().
-        unw_resume(&cursor2);
+        unw_resume(cursor);
         break;
       default:
         // Personality routine returned an unknown result code.
@@ -332,7 +329,7 @@
   _Unwind_Action lastAction =
       (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
   (*stop)(1, lastAction, exception_object->exception_class, exception_object,
-          (struct _Unwind_Context *)(&cursor2), stop_parameter);
+          (struct _Unwind_Context *)(cursor), stop_parameter);
 
   // Clean up phase did not resume at the frame that the search phase said it
   // would.
@@ -346,6 +343,7 @@
   _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
                        (void *)exception_object);
   unw_context_t uc;
+  unw_cursor_t cursor;
   unw_getcontext(&uc);
 
   // Mark that this is a non-forced unwind, so _Unwind_Resume()
@@ -354,12 +352,12 @@
   exception_object->private_2 = 0;
 
   // phase 1: the search phase
-  _Unwind_Reason_Code phase1 = unwind_phase1(&uc, exception_object);
+  _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object);
   if (phase1 != _URC_NO_REASON)
     return phase1;
 
   // phase 2: the clean up phase
-  return unwind_phase2(&uc, exception_object);
+  return unwind_phase2(&uc, &cursor, exception_object);
 }
 
 
@@ -379,14 +377,15 @@
 _Unwind_Resume(_Unwind_Exception *exception_object) {
   _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", (void *)exception_object);
   unw_context_t uc;
+  unw_cursor_t cursor;
   unw_getcontext(&uc);
 
   if (exception_object->private_1 != 0)
-    unwind_phase2_forced(&uc, exception_object,
+    unwind_phase2_forced(&uc, &cursor, exception_object,
                          (_Unwind_Stop_Fn) exception_object->private_1,
                          (void *)exception_object->private_2);
   else
-    unwind_phase2(&uc, exception_object);
+    unwind_phase2(&uc, &cursor, exception_object);
 
   // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
   _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
@@ -403,6 +402,7 @@
   _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
                        (void *)exception_object, (void *)(uintptr_t)stop);
   unw_context_t uc;
+  unw_cursor_t cursor;
   unw_getcontext(&uc);
 
   // Mark that this is a forced unwind, so _Unwind_Resume() can do
@@ -411,7 +411,7 @@
   exception_object->private_2 = (uintptr_t) stop_parameter;
 
   // do it
-  return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter);
+  return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter);
 }