]> granicus.if.org Git - gc/commitdiff
2009-02-28 Hans Boehm <Hans.Boehm@hp.com> (With input from Ivan Maidansky)
authorhboehm <hboehm>
Sat, 28 Feb 2009 23:29:44 +0000 (23:29 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:44 +0000 (21:06 +0400)
* win32_threads.c (GC_push_stack_for): Yet another attempt
at the stack_min finding logic.  Try to clean up the existing code
while minimizing VirtualQuery calls.
(GC_win32_start_inner): Register thread before GC_printf.
Produce more output with DEBUG_THREADS.
*include/gc.h: Update obsolete comments.

ChangeLog
include/gc.h
win32_threads.c

index 7547a662755e748572d8f6d82f604a6eff5db6f7..6684b57433abe7a519abf36c7faeed783c7580d6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-02-28  Hans Boehm <Hans.Boehm@hp.com> (With input from Ivan Maidansky)
+       * win32_threads.c (GC_push_stack_for): Yet another attempt
+       at the stack_min finding logic.  Try to clean up the existing code
+       while minimizing VirtualQuery calls.
+       (GC_win32_start_inner): Register thread before GC_printf.
+       Produce more output with DEBUG_THREADS.
+       *include/gc.h: Update obsolete comments.
+
 2009-02-24  Hans Boehm <Hans.Boehm@hp.com> (Really Ivan Maidansky)
        * tests/test.c:
        (gcj_class_struct2): Use cast instead of l suffix.
index 335dd09a3718917e7ec5b2768e0da10fb485b547..ba4ca32cc1eae06ed334b04b8424b987684ee453 100644 (file)
@@ -56,9 +56,6 @@
   typedef unsigned long GC_word;
   typedef long GC_signed_word;
 #else
-  /* Win64 isn't really supported yet, but this is the first step. And */
-  /* it might cause error messages to show up in more plausible places.        */
-  /* This needs basetsd.h, which is included by windows.h.             */
 #ifdef __int64
   typedef unsigned __int64 GC_word;
   typedef __int64 GC_signed_word;
@@ -274,9 +271,8 @@ GC_API void GC_CALL GC_init(void);
  * be reachable.  GC_malloc_uncollectable and GC_free called on the resulting
  * object implicitly update GC_non_gc_bytes appropriately.
  *
- * Note that the GC_malloc_stubborn support is stubbed out by default
- * starting in 6.0.  GC_malloc_stubborn is an alias for GC_malloc unless
- * the collector is built with STUBBORN_ALLOC defined.
+ * Note that the GC_malloc_stubborn support doesn't really
+ * exist anymore.  MANUAL_VDB provides comparable functionality.
  */
 GC_API void * GC_CALL GC_malloc(size_t size_in_bytes);
 GC_API void * GC_CALL GC_malloc_atomic(size_t size_in_bytes);
index 2c56ffd2cc19610f82db8cd8fa6ec77731bbe1ee..19318144f9c97893acdf1dd07d9b9540689df5da 100644 (file)
@@ -944,36 +944,53 @@ STATIC void GC_push_stack_for(GC_thread thread)
 #       endif
       } /* ! current thread */
 
-      /* If got sp value seems to be correct (at least, less than the  */
-      /* bottom of the stack) then do its further validation by quick  */
-      /* probing the memory region at it.                              */
       /* Set stack_min to the lowest address in the thread stack,      */
+      /* or to an address in the thread stack no larger than sp,       */
       /* taking advantage of the old value to avoid slow traversals    */
       /* of large stacks.                                              */
       if (thread -> last_stack_min == ADDR_LIMIT) {
        stack_min = GC_get_stack_min(thread -> stack_base);
+        thread -> last_stack_min = stack_min;
       } else {
-#       ifdef MSWINCE
-         stack_min = GC_get_stack_min(thread -> stack_base);
-#       else
-          if (GC_may_be_in_stack(thread -> last_stack_min)) {
-            stack_min = GC_get_stack_min(thread -> last_stack_min);
-         } else {
+       if (sp < thread -> stack_base && sp >= thread -> last_stack_min) {
+           stack_min = sp;
+       } else {
+#         ifdef MSWINCE
            stack_min = GC_get_stack_min(thread -> stack_base);
-         }
-#      endif
+#         else
+            if (GC_may_be_in_stack(thread -> last_stack_min)) {
+              stack_min = GC_get_stack_min(thread -> last_stack_min);
+           } else {
+             /* Stack shrunk?  Is this possible? */
+             stack_min = GC_get_stack_min(thread -> stack_base);
+           }
+#        endif
+          thread -> last_stack_min = stack_min;
+       }
       }
-      thread -> last_stack_min = stack_min;
+      GC_ASSERT(stack_min == GC_get_stack_min(thread -> stack_base)
+               || sp >= stack_min && stack_min < thread -> stack_base
+                  && stack_min > GC_get_stack_min(thread -> stack_base));
 
       if (sp >= stack_min && sp < thread->stack_base) {
 #       ifdef DEBUG_THREADS
-         GC_printf("Pushing thread from %p to %p for 0x%x from 0x%x\n",
-                   sp, thread -> stack_base, (int)thread -> id, (int)me);
+         GC_printf("Pushing stack for 0x%x from sp %p to %p from 0x%x\n",
+                   (int)thread -> id, sp, thread -> stack_base, (int)me);
 #       endif
         GC_push_all_stack(sp, thread->stack_base);
       } else {
-        WARN("Thread stack pointer 0x%lx out of range, pushing everything\n",
-            (unsigned long)(size_t)sp);
+       /* If not current thread then it is possible for sp to point to */
+       /* the guarded (untouched yet) page just below the current      */
+       /* stack_min of the thread.                                     */
+       if (thread -> id == me || sp >= thread->stack_base
+               || sp + GC_page_size < stack_min)
+         WARN("Thread stack pointer 0x%lx out of range, pushing everything\n",
+               (unsigned long)(size_t)sp);
+#       ifdef DEBUG_THREADS
+         GC_printf("Pushing stack for 0x%x from (min) %p to %p from 0x%x\n",
+                   (int)thread -> id, stack_min,
+                   thread -> stack_base, (int)me);
+#       endif
         GC_push_all_stack(stack_min, thread->stack_base);
       }
     } /* thread looks live */
@@ -1470,12 +1487,12 @@ STATIC void * GC_CALLBACK GC_win32_start_inner(struct GC_stack_base *sb,
     void * ret;
     thread_args *args = (thread_args *)arg;
 
+    GC_register_my_thread(sb); /* This waits for an in-progress GC. */
+
 #   if DEBUG_WIN32_THREADS
       GC_printf("thread 0x%x starting...\n", (unsigned)GetCurrentThreadId());
 #   endif
 
-    GC_register_my_thread(sb); /* This waits for an in-progress GC. */
-
     /* Clear the thread entry even if we exit with an exception.       */
     /* This is probably pointless, since an uncaught exception is      */
     /* supposed to result in the process being killed.                 */
@@ -2128,6 +2145,9 @@ void GC_mark_thread_local_free_lists(void)
     
     for (i = 0; i < THREAD_TABLE_SZ; ++i) {
       for (p = GC_threads[i]; 0 != p; p = p -> next) {
+#       ifdef DEBUG_THREADS
+         GC_printf("Marking thread locals for 0x%x\n", p -> id);
+#      endif
        GC_mark_thread_local_fls_for(&(p->tlfs));
       }
     }