You who are about to crash (Norbert & Jerry, this means you!),
I salute you:
Please apply the enclosed patch (against current CVS). After that
salutation, it should be clear why this is not in CVS. :-)
I found a possible crash left unguarded in Mike's earlier patch. I
have my suspicions about other opcodes, but let's see if this helps.
Build is OK, I'm sending this post from the patched XEmacs, but since
with Mike's patch to GCPRO_STACK Fset I only crash a little more often
once a day, I can't say this is "tested" yet.
Bvarbind definitely calls Fset through specbind_magic(). I have my
suspicions about Bset_buffer, and maybe some other B.*set.* opcodes.
Mike, please look at those opcodes: Maybe your oracle is faster than
me trying to trace function calls....
Of course it passes 100% of the tests. :-)
>>>> "sjt" == Stephen J Turnbull
<stephen(a)xemacs.org> writes:
sjt> Per this discussion I've reverted the GCPRO_STACK patch temporarily.
Index: src/ChangeLog
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/ChangeLog,v
retrieving revision 1.649
diff -u -U0 -r1.649 ChangeLog
--- src/ChangeLog 1 Nov 2003 14:54:53 -0000 1.649
+++ src/ChangeLog 4 Nov 2003 06:48:54 -0000
@@ -0,0 +1,13 @@
+2003-11-04 Stephen J. Turnbull <stephen(a)xemacs.org>
+
+ * bytecode.c (execute_optimized_program): GCPRO_STACK Bvarbind, too.
+
+ Restore 2003-08-12 Mike Sperber <mike(a)xemacs.org>:
+
+ * bytecode.c (GCPRO_STACK): Added.
+ (execute_optimized_program): Use GCPRO_STACK, fixing a space leak:
+ Formerly, the byte-code engine would always hold on to the entire
+ stack memory area, including the stuff above the top. Now, we
+ adjust the GCPRO record via GCPRO_STACK just before a GC may
+ occur.
+
Index: src/bytecode.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/bytecode.c,v
retrieving revision 1.37
diff -u -u -r1.37 bytecode.c
--- src/bytecode.c 21 Oct 2003 08:21:02 -0000 1.37
+++ src/bytecode.c 4 Nov 2003 06:49:02 -0000
@@ -447,6 +447,8 @@
but don't pop it. */
#define TOP (*stack_ptr)
+#define GCPRO_STACK (gcpro1.nvars = stack_ptr - stack_beg)
+
/* The actual interpreter for byte code.
This function has been seriously optimized for performance.
Don't change the constructs unless you are willing to do
@@ -460,8 +462,8 @@
{
/* This function can GC */
REGISTER const Opbyte *program_ptr = (Opbyte *) program;
- REGISTER Lisp_Object *stack_ptr
- = alloca_array (Lisp_Object, stack_depth + 1);
+ Lisp_Object *stack_beg = alloca_array (Lisp_Object, stack_depth + 1);
+ REGISTER Lisp_Object *stack_ptr = stack_beg;
int speccount = specpdl_depth ();
struct gcpro gcpro1;
@@ -471,23 +473,11 @@
#endif
#ifdef ERROR_CHECK_BYTE_CODE
- Lisp_Object *stack_beg = stack_ptr;
Lisp_Object *stack_end = stack_beg + stack_depth;
#endif
- /* Initialize all the objects on the stack to Qnil,
- so we can GCPRO the whole stack.
- The first element of the stack is actually a dummy. */
- {
- int i;
- Lisp_Object *p;
- for (i = stack_depth, p = stack_ptr; i--;)
- *++p = Qnil;
- }
-
GCPRO1 (stack_ptr[1]);
- gcpro1.nvars = stack_depth;
-
+
while (1)
{
REGISTER Opcode opcode = (Opcode) READ_UINT_1;
@@ -512,7 +502,11 @@
if (opcode >= Bconstant)
PUSH (constants_data[opcode - Bconstant]);
else
- stack_ptr = execute_rare_opcode (stack_ptr, program_ptr, opcode);
+ {
+ /* We're not sure what these do, so better safe than sorry. */
+ GCPRO_STACK;
+ stack_ptr = execute_rare_opcode (stack_ptr, program_ptr, opcode);
+ }
break;
case Bvarref:
@@ -549,8 +543,12 @@
Lisp_Object new_value = POP;
if (!SYMBOL_VALUE_MAGIC_P (old_value) || UNBOUNDP (old_value))
symbol_ptr->value = new_value;
- else
+ else {
+ /* Fset may call magic handlers */
+ GCPRO_STACK;
Fset (symbol, new_value);
+ }
+
break;
}
@@ -583,7 +581,11 @@
#endif
}
else
- specbind_magic (symbol, new_value);
+ {
+ /* does an Fset, may call magic handlers */
+ GCPRO_STACK;
+ specbind_magic (symbol, new_value);
+ }
break;
}
@@ -597,6 +599,7 @@
case Bcall+7:
n = (opcode < Bcall+6 ? opcode - Bcall :
opcode == Bcall+6 ? READ_UINT_1 : READ_UINT_2);
+ GCPRO_STACK;
DISCARD (n);
#ifdef BYTE_CODE_METER
if (byte_metering_on && SYMBOLP (TOP))
@@ -974,6 +977,8 @@
case Bset:
{
Lisp_Object arg = POP;
+ /* Fset may call magic handlers */
+ GCPRO_STACK;
TOP = Fset (TOP, arg);
break;
}
--
Institute of Policy and Planning Sciences
http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
Ask not how you can "do" free software business;
ask what your business can "do for" free software.