comparison src/bytecode.c @ 1626:5cec7ab01719

[xemacs-hg @ 2003-08-16 14:18:36 by michaels] 2003-08-12 Mike Sperber <mike@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.
author michaels
date Sat, 16 Aug 2003 14:18:38 +0000
parents e22b0213b713
children 6c996a26d761
comparison
equal deleted inserted replaced
1625:b7261453102e 1626:5cec7ab01719
445 445
446 /* Get the value which is at the top of the execution stack, 446 /* Get the value which is at the top of the execution stack,
447 but don't pop it. */ 447 but don't pop it. */
448 #define TOP (*stack_ptr) 448 #define TOP (*stack_ptr)
449 449
450 #define GCPRO_STACK (gcpro1.nvars = stack_ptr - stack_beg)
451
450 /* The actual interpreter for byte code. 452 /* The actual interpreter for byte code.
451 This function has been seriously optimized for performance. 453 This function has been seriously optimized for performance.
452 Don't change the constructs unless you are willing to do 454 Don't change the constructs unless you are willing to do
453 real benchmarking and profiling work -- martin */ 455 real benchmarking and profiling work -- martin */
454 456
458 int stack_depth, 460 int stack_depth,
459 Lisp_Object *constants_data) 461 Lisp_Object *constants_data)
460 { 462 {
461 /* This function can GC */ 463 /* This function can GC */
462 REGISTER const Opbyte *program_ptr = (Opbyte *) program; 464 REGISTER const Opbyte *program_ptr = (Opbyte *) program;
463 REGISTER Lisp_Object *stack_ptr 465 Lisp_Object *stack_beg = alloca_array (Lisp_Object, stack_depth + 1);
464 = alloca_array (Lisp_Object, stack_depth + 1); 466 REGISTER Lisp_Object *stack_ptr = stack_beg;
465 int speccount = specpdl_depth (); 467 int speccount = specpdl_depth ();
466 struct gcpro gcpro1; 468 struct gcpro gcpro1;
467 469
468 #ifdef BYTE_CODE_METER 470 #ifdef BYTE_CODE_METER
469 Opcode this_opcode = 0; 471 Opcode this_opcode = 0;
470 Opcode prev_opcode; 472 Opcode prev_opcode;
471 #endif 473 #endif
472 474
473 #ifdef ERROR_CHECK_BYTE_CODE 475 #ifdef ERROR_CHECK_BYTE_CODE
474 Lisp_Object *stack_beg = stack_ptr;
475 Lisp_Object *stack_end = stack_beg + stack_depth; 476 Lisp_Object *stack_end = stack_beg + stack_depth;
476 #endif 477 #endif
477 478
478 /* Initialize all the objects on the stack to Qnil,
479 so we can GCPRO the whole stack.
480 The first element of the stack is actually a dummy. */
481 {
482 int i;
483 Lisp_Object *p;
484 for (i = stack_depth, p = stack_ptr; i--;)
485 *++p = Qnil;
486 }
487
488 GCPRO1 (stack_ptr[1]); 479 GCPRO1 (stack_ptr[1]);
489 gcpro1.nvars = stack_depth; 480
490
491 while (1) 481 while (1)
492 { 482 {
493 REGISTER Opcode opcode = (Opcode) READ_UINT_1; 483 REGISTER Opcode opcode = (Opcode) READ_UINT_1;
494 #ifdef ERROR_CHECK_BYTE_CODE 484 #ifdef ERROR_CHECK_BYTE_CODE
495 if (stack_ptr > stack_end) 485 if (stack_ptr > stack_end)
510 500
511 default: 501 default:
512 if (opcode >= Bconstant) 502 if (opcode >= Bconstant)
513 PUSH (constants_data[opcode - Bconstant]); 503 PUSH (constants_data[opcode - Bconstant]);
514 else 504 else
515 stack_ptr = execute_rare_opcode (stack_ptr, program_ptr, opcode); 505 {
506 GCPRO_STACK;
507 stack_ptr = execute_rare_opcode (stack_ptr, program_ptr, opcode);
508 }
516 break; 509 break;
517 510
518 case Bvarref: 511 case Bvarref:
519 case Bvarref+1: 512 case Bvarref+1:
520 case Bvarref+2: 513 case Bvarref+2:
595 case Bcall+5: 588 case Bcall+5:
596 case Bcall+6: 589 case Bcall+6:
597 case Bcall+7: 590 case Bcall+7:
598 n = (opcode < Bcall+6 ? opcode - Bcall : 591 n = (opcode < Bcall+6 ? opcode - Bcall :
599 opcode == Bcall+6 ? READ_UINT_1 : READ_UINT_2); 592 opcode == Bcall+6 ? READ_UINT_1 : READ_UINT_2);
593 GCPRO_STACK;
600 DISCARD (n); 594 DISCARD (n);
601 #ifdef BYTE_CODE_METER 595 #ifdef BYTE_CODE_METER
602 if (byte_metering_on && SYMBOLP (TOP)) 596 if (byte_metering_on && SYMBOLP (TOP))
603 { 597 {
604 Lisp_Object val = Fget (TOP, Qbyte_code_meter, Qnil); 598 Lisp_Object val = Fget (TOP, Qbyte_code_meter, Qnil);