guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. v2.1.0-623-g7dba1c2


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. v2.1.0-623-g7dba1c2
Date: Fri, 31 Jan 2014 20:44:46 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=7dba1c2ff139be60ccf7f81debd4bb85a07ab8f6

The branch, master has been updated
       via  7dba1c2ff139be60ccf7f81debd4bb85a07ab8f6 (commit)
       via  7161ec1133d33a4c06261dd6a621026c3d4d1ef5 (commit)
      from  8dcabf600386e1a4e7dbfd1d41f312f0c3e2179c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7dba1c2ff139be60ccf7f81debd4bb85a07ab8f6
Author: Andy Wingo <address@hidden>
Date:   Fri Jan 31 21:41:36 2014 +0100

    Return unused parts of the stack to the OS
    
    * libguile/vm.h (struct scm_vm): Reorder fields.  Add "sp_max_since_gc"
      field.
    * libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
    * libguile/vm.c (vm_return_to_continuation)
      (vm_reinstate_partial_continuation, scm_call_n): In places where we
      could increase the stack height, update sp_max_since_gc.
      (vm_expand_stack): Relocate sp_max_since_gc on expansion.
      (scm_bootstrap_vm): Record the page size using gnulib's getpagesize.
      (return_unused_stack_to_os): New routine, run when marking stacks.

commit 7161ec1133d33a4c06261dd6a621026c3d4d1ef5
Author: Andy Wingo <address@hidden>
Date:   Fri Jan 31 20:31:31 2014 +0100

    Micro-optimization to scm_i_vm_mark_stack
    
    * libguile/vm.c (scm_i_vm_mark_stack): Micro-optimize GC_MARK_AND_PUSH
      to cache the plausible heap bounds locally.

-----------------------------------------------------------------------

Summary of changes:
 libguile/vm-engine.c |    4 +++
 libguile/vm.c        |   70 ++++++++++++++++++++++++++++++++++++++++++-------
 libguile/vm.h        |    7 +++--
 3 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index 0caad8a..fe0329f 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -196,6 +196,8 @@
   do {                                                              \
     vp->sp = LOCAL_ADDRESS (n - 1);                                 \
     CHECK_OVERFLOW ();                                              \
+    if (vp->sp > vp->sp_max_since_gc)                               \
+      vp->sp_max_since_gc = vp->sp;                                 \
   } while (0)
 
 /* Reset the current frame to hold N locals.  Used when we know that no
@@ -203,6 +205,8 @@
 #define RESET_FRAME(n)                                              \
   do {                                                              \
     vp->sp = LOCAL_ADDRESS (n - 1);                                 \
+    if (vp->sp > vp->sp_max_since_gc)                               \
+      vp->sp_max_since_gc = vp->sp;                                 \
   } while (0)
 
 /* Compute the number of locals in the frame.  At a call, this is equal
diff --git a/libguile/vm.c b/libguile/vm.c
index 43ade82..7f88e46 100644
--- a/libguile/vm.c
+++ b/libguile/vm.c
@@ -28,6 +28,7 @@
 #include <alignof.h>
 #include <string.h>
 #include <stdint.h>
+#include <unistd.h>
 
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
@@ -142,6 +143,8 @@ vm_return_to_continuation (struct scm_vm *vp, SCM cont, 
size_t n, SCM *argv)
         vp->sp++;
         *vp->sp = argv_copy[i];
       }
+    if (vp->sp > vp->sp_max_since_gc)
+      vp->sp_max_since_gc = vp->sp;
     vp->ip = cp->ra;
   }
 }
@@ -288,6 +291,8 @@ vm_abort (struct scm_vm *vp, SCM tag,
   scm_c_abort (vp, tag, nstack + tail_len, argv, current_registers);
 }
 
+static void vm_expand_stack (struct scm_vm *vp) SCM_NOINLINE;
+
 static void
 vm_reinstate_partial_continuation (struct scm_vm *vp, SCM cont,
                                    size_t n, SCM *argv,
@@ -303,17 +308,25 @@ vm_reinstate_partial_continuation (struct scm_vm *vp, SCM 
cont,
   memcpy (argv_copy, argv, n * sizeof(SCM));
 
   cp = SCM_VM_CONT_DATA (cont);
-  base = SCM_FRAME_LOCALS_ADDRESS (vp->fp);
-  reloc = cp->reloc + (base - cp->stack_base);
+
+  while (1)
+    {
+      scm_t_ptrdiff saved_stack_height = vp->sp - vp->stack_base;
+
+      base = SCM_FRAME_LOCALS_ADDRESS (vp->fp);
+      reloc = cp->reloc + (base - cp->stack_base);
+
+      vp->sp = base + cp->stack_size + n + 1;
+      if (vp->sp < vp->stack_limit)
+        break;
+
+      vm_expand_stack (vp);
+      vp->sp = vp->stack_base + saved_stack_height;
+    }
 
 #define RELOC(scm_p)                                           \
   (((SCM *) (scm_p)) + reloc)
 
-  if ((base - vp->stack_base) + cp->stack_size + n + 1 > vp->stack_size)
-    scm_misc_error ("vm-engine",
-                    "not enough space to instate partial continuation",
-                    scm_list_1 (cont));
-
   memcpy (base, cp->stack_base, cp->stack_size * sizeof (SCM));
 
   /* now relocate frame pointers */
@@ -336,6 +349,9 @@ vm_reinstate_partial_continuation (struct scm_vm *vp, SCM 
cont,
       *vp->sp = argv_copy[i];
     }
 
+  if (vp->sp > vp->sp_max_since_gc)
+      vp->sp_max_since_gc = vp->sp;
+
   /* The prompt captured a slice of the dynamic stack.  Here we wind
      those entries onto the current thread's stack.  We also have to
      relocate any prompts that we see along the way.  */
@@ -672,7 +688,6 @@ initialize_default_stack_size (void)
     default_max_stack_size = size;
 }
 
-static void vm_expand_stack (struct scm_vm *vp) SCM_NOINLINE;
 #define VM_NAME vm_regular_engine
 #define VM_USE_HOOKS 0
 #define FUNC_NAME "vm-regular-engine"
@@ -788,6 +803,27 @@ make_vm (void)
 }
 #undef FUNC_NAME
 
+static size_t page_size;
+
+static void
+return_unused_stack_to_os (struct scm_vm *vp)
+{
+#if HAVE_SYS_MMAN_H
+  scm_t_uintptr start = (scm_t_uintptr) vp->sp;
+  scm_t_uintptr end = (scm_t_uintptr) vp->sp_max_since_gc;
+
+  start = ((start - 1U) | (page_size - 1U)) + 1U; /* round up */
+  end = ((end - 1U) | (page_size - 1U)) + 1U; /* round up */
+
+  /* Return these pages to the OS.  The next time they are paged in,
+     they will be zeroed.  */
+  if (start < end)
+    madvise ((void *) start, end - start, MADV_DONTNEED);
+
+  vp->sp_max_since_gc = vp->sp;
+#endif
+}
+
 /* Mark the VM stack region between its base and its current top.  */
 struct GC_ms_entry *
 scm_i_vm_mark_stack (struct scm_vm *vp, struct GC_ms_entry *mark_stack_ptr,
@@ -800,13 +836,16 @@ scm_i_vm_mark_stack (struct scm_vm *vp, struct 
GC_ms_entry *mark_stack_ptr,
      hooks, and providing dead slot maps for all points in a program
      would take a prohibitive amount of space.  */
   const scm_t_uint8 *dead_slots = NULL;
+  scm_t_uintptr upper = (scm_t_uintptr) GC_greatest_plausible_heap_addr;
+  scm_t_uintptr lower = (scm_t_uintptr) GC_least_plausible_heap_addr;
 
   for (fp = vp->fp, sp = vp->sp; fp; fp = SCM_FRAME_DYNAMIC_LINK (fp))
     {
       for (; sp >= &SCM_FRAME_LOCAL (fp, 0); sp--)
         {
           SCM elt = *sp;
-          if (SCM_NIMP (elt))
+          if (SCM_NIMP (elt)
+              && SCM_UNPACK (elt) >= lower && SCM_UNPACK (elt) <= upper)
             {
               if (dead_slots)
                 {
@@ -820,7 +859,7 @@ scm_i_vm_mark_stack (struct scm_vm *vp, struct GC_ms_entry 
*mark_stack_ptr,
                     }
                 }
 
-              mark_stack_ptr = GC_MARK_AND_PUSH ((GC_word *) elt,
+              mark_stack_ptr = GC_mark_and_push ((void *) elt,
                                                  mark_stack_ptr,
                                                  mark_stack_limit,
                                                  NULL);
@@ -835,6 +874,8 @@ scm_i_vm_mark_stack (struct scm_vm *vp, struct GC_ms_entry 
*mark_stack_ptr,
         scm_find_dead_slot_map_unlocked (SCM_FRAME_RETURN_ADDRESS (fp));
     }
 
+  return_unused_stack_to_os (vp);
+
   return mark_stack_ptr;
 }
 
@@ -881,6 +922,7 @@ vm_expand_stack (struct scm_vm *vp)
           SCM *fp;
           vp->fp += reloc;
           vp->sp += reloc;
+          vp->sp_max_since_gc += reloc;
           fp = vp->fp;
           while (fp)
             {
@@ -979,6 +1021,9 @@ scm_call_n (SCM proc, SCM *argv, size_t nargs)
   vp->fp = &base[5];
   vp->sp = &SCM_FRAME_LOCAL (vp->fp, nargs);
 
+  if (vp->sp > vp->sp_max_since_gc)
+    vp->sp_max_since_gc = vp->sp;
+
   {
     int resume = SCM_I_SETJMP (registers);
       
@@ -1207,6 +1252,11 @@ scm_bootstrap_vm (void)
                             (scm_t_extension_init_func)scm_init_vm_builtins,
                             NULL);
 
+  page_size = getpagesize ();
+  /* page_size should be a power of two.  */
+  if (page_size & (page_size - 1))
+    abort ();
+
   initialize_default_stack_size ();
 
   sym_vm_run = scm_from_latin1_symbol ("vm-run");
diff --git a/libguile/vm.h b/libguile/vm.h
index 6a25732..9edced1 100644
--- a/libguile/vm.h
+++ b/libguile/vm.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, 
Inc.
+/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013, 2014 Free Software 
Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -39,10 +39,11 @@ struct scm_vm {
   scm_t_uint32 *ip;            /* instruction pointer */
   SCM *sp;                     /* stack pointer */
   SCM *fp;                     /* frame pointer */
-  size_t stack_size;           /* stack size */
-  SCM *stack_base;             /* stack base address */
   SCM *stack_limit;            /* stack limit address */
   int trace_level;              /* traces enabled if trace_level > 0 */
+  SCM *sp_max_since_gc;         /* highest sp since last gc */
+  size_t stack_size;           /* stack size */
+  SCM *stack_base;             /* stack base address */
   size_t max_stack_size;
   SCM hooks[SCM_VM_NUM_HOOKS]; /* hooks */
   int engine;                   /* which vm engine we're using */


hooks/post-receive
-- 
GNU Guile



reply via email to

[Prev in Thread] Current Thread [Next in Thread]