From: Bob Rogers <[EMAIL PROTECTED]>
   Date: Mon, 21 Apr 2008 18:54:19 -0400

      From: "Patrick R. Michaud" <[EMAIL PROTECTED]>
      Date: Mon, 21 Apr 2008 15:42:27 -0500

      . . . If it looks like having a separate stack for bsr/ret is
      workable then I'll go at it that way.

   Fair enough.  FWIW, I'm now working on a simple hack that should show
   how much speedup we can expect.

The hack is attached; it isn't headerized, has some coding standards
failures, and leaks memory, so it's incomplete.  Disappointingly, it
produces an overall speedup of less than 4% in building gen_actions.pir
in r27087 (which has chromatic's ref-counting speedup).

   And it fails t/pmc/continuation.t test 4 ("continuations preserve
bsr/ret state"), as expected.  I don't think a 4% speedup is worth it,
so I'm giving up on it.  Maybe somebody else will find a way to improve
it.

   A warning, though:  Do "make clean" after applying the patch, or the
new "parrot" will consume all memory.  I suspect there is some code that
uses Parrot_Context that doesn't have the right dependencies, so is not
recompiled when interpreter.h is changed.

                                        -- Bob

[P.S.  Oops.]

*** Give bsr/ret a stack of their own ***
* include/parrot/interpreter.h:
   + Add bsr_stack, bsr_allocated, and bsr_stack_size members to
     Parrot_Context.
* src/gc/register.c:
   + (init_context):  Initialize bsr_stack.
* src/stacks.c:
   + (Parrot_bsr_stack_push, Parrot_bsr_stack_pop):  New.  (Probably
     need a better permanent home for them.)
* src/ops/core.ops:
   + (bsr, ret, jsr):  Use Parrot_bsr_stack_push/Parrot_bsr_stack_pop.

Diffs between last version checked in and current workfile(s):

Index: include/parrot/interpreter.h
===================================================================
--- include/parrot/interpreter.h        (revision 27087)
+++ include/parrot/interpreter.h        (working copy)
@@ -218,6 +218,10 @@
     struct Stack_Chunk *user_stack;     /* Base of the scratch stack */
     PMC      *lex_pad;                  /* LexPad PMC */
     struct Parrot_Context *outer_ctx;   /* outer context, if a closure */
+    opcode_t **bsr_stack;      /* pointer to bsr/ret addresses, lazily 
allocated
+                                  by Parrot_bsr_stack_push. */
+    UINTVAL bsr_allocated;     /* allocated bsr_stack size */
+    UINTVAL bsr_stack_size;    /* used bsr_stack size */
     UINTVAL warns;             /* Keeps track of what warnings
                                 * have been activated */
     UINTVAL errors;            /* fatals that can be turned off */
Index: src/gc/register.c
===================================================================
--- src/gc/register.c   (revision 27087)
+++ src/gc/register.c   (working copy)
@@ -297,6 +297,9 @@
     ctx->current_cont = NULL;
     ctx->current_object = NULL; /* RT#46181 who clears it?  */
     ctx->current_HLL = 0;
+    /* We don't need to initialize bsr_allocated or bsr_stack_size, because 
they
+       won't be examined if bsr_stack is NULL. */
+    ctx->bsr_stack = NULL;
 
     if (old) {
         /* some items should better be COW copied */
Index: src/stacks.c
===================================================================
--- src/stacks.c        (revision 27087)
+++ src/stacks.c        (working copy)
@@ -484,6 +484,49 @@
                 height, dynamic_env, dynamic_env->name);
 }
 
+/*** bsr/ret stack support ***/
+
+PARROT_API
+void
+Parrot_bsr_stack_push(PARROT_INTERP, ARGIN(opcode_t *return_addr))
+{
+    parrot_context_t *context = CONTEXT(interp);
+
+    if (! context->bsr_stack) {
+        /* Need a new stack. */
+        UINTVAL size = 100;
+        /* fprintf(stderr, "[first alloc for %p]\n", context); */
+        context->bsr_allocated  = size;
+        context->bsr_stack_size = 0;
+        context->bsr_stack      = (opcode_t 
**)mem_sys_allocate(size*sizeof(opcode_t *));
+    }
+    else if (context->bsr_stack_size >= context->bsr_allocated) {
+        /* Need a bigger stack. */
+        UINTVAL size = 2*context->bsr_allocated;
+        /* fprintf(stderr, "[realloc for %p (currently %p), from %d to %d]\n",
+                context, context->bsr_stack,
+                (int)context->bsr_allocated, (int)size); */
+        if (size > 1000000)
+            real_exception(interp, NULL, 1, "Too many 'bsr' calls\n");
+        context->bsr_stack      = (opcode_t 
**)mem_sys_realloc(context->bsr_stack, size*sizeof(opcode_t *));
+        context->bsr_allocated  = size;
+    }
+
+    /* Push it. */
+    context->bsr_stack[context->bsr_stack_size++] = return_addr;
+}
+
+PARROT_API
+opcode_t *
+Parrot_bsr_stack_pop(PARROT_INTERP)
+{
+    parrot_context_t *context = CONTEXT(interp);
+
+    if (! context->bsr_stack || context->bsr_stack_size == 0)
+        real_exception(interp, NULL, 1, "'ret' without 'bsr'\n");
+    return context->bsr_stack[--context->bsr_stack_size];
+}
+
 /*
 
 =back
Index: src/ops/core.ops
===================================================================
--- src/ops/core.ops    (revision 27087)
+++ src/ops/core.ops    (working copy)
@@ -101,6 +101,8 @@
 
 =cut
 
+/* ' */
+
 inline op noop() :base_core {
     goto NEXT();
 }
@@ -217,8 +219,7 @@
 =cut
 
 inline op bsr(label INT) :base_core,check_event {
-    stack_push(interp, &interp->dynamic_env,
-             expr NEXT(),  STACK_ENTRY_DESTINATION, STACK_CLEANUP_NULL);
+    Parrot_bsr_stack_push(interp, expr NEXT());
     goto OFFSET($1);
 }
 
@@ -229,7 +230,8 @@
 =cut
 
 inline op ret() {
-    goto POP();
+    opcode_t * loc = Parrot_bsr_stack_pop(interp);
+    goto ADDRESS(loc);
 }
 
 
@@ -244,8 +246,7 @@
 
 inline op jsr(label INT) :base_core,check_event {
     opcode_t * loc;
-    stack_push(interp, &interp->dynamic_env,
-             expr NEXT(),  STACK_ENTRY_DESTINATION, STACK_CLEANUP_NULL);
+    Parrot_bsr_stack_push(interp, expr NEXT());
     loc = INTVAL2PTR(opcode_t *, $1);
     goto ADDRESS(loc);
 }

End of diffs.

Reply via email to