Mercurial > hg > xemacs-beta
comparison src/bytecode.c @ 1920:c66036f59678
[xemacs-hg @ 2004-02-20 07:29:16 by stephent]
GCPRO documentation <87y8qynrj0.fsf@tleepslib.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Fri, 20 Feb 2004 07:29:23 +0000 |
parents | 3d25fd3d9ac4 |
children | 9c872f33ecbe |
comparison
equal
deleted
inserted
replaced
1919:9bde73b8c020 | 1920:c66036f59678 |
---|---|
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 /* See comment before the big switch in execute_optimized_program(). */ | |
450 #define GCPRO_STACK (gcpro1.nvars = stack_ptr - stack_beg) | 451 #define GCPRO_STACK (gcpro1.nvars = stack_ptr - stack_beg) |
451 | 452 |
452 /* The actual interpreter for byte code. | 453 /* The actual interpreter for byte code. |
453 This function has been seriously optimized for performance. | 454 This function has been seriously optimized for performance. |
454 Don't change the constructs unless you are willing to do | 455 Don't change the constructs unless you are willing to do |
474 | 475 |
475 #ifdef ERROR_CHECK_BYTE_CODE | 476 #ifdef ERROR_CHECK_BYTE_CODE |
476 Lisp_Object *stack_end = stack_beg + stack_depth; | 477 Lisp_Object *stack_end = stack_beg + stack_depth; |
477 #endif | 478 #endif |
478 | 479 |
479 #if STATIC_GCPRO_STACK | 480 /* We used to GCPRO the whole interpreter stack before entering this while |
480 /* Initialize all the objects on the stack to Qnil, | 481 loop (21.5.14 and before), but that interferes with collection of weakly |
481 so we can GCPRO the whole stack. | 482 referenced objects. Although strictly speaking there's no promise that |
482 The first element of the stack is actually a dummy. */ | 483 weak references will disappear by any given point in time, they should |
483 { | 484 be collected at the first opportunity. Waiting until exit from the |
484 int i; | 485 function caused test failures because "stale" objects "above" the top of |
485 Lisp_Object *p; | 486 the stack were still GCPROed, and they were not getting collected until |
486 for (i = stack_depth, p = stack_ptr; i--;) | 487 after exit from the (byte-compiled) test! |
487 *++p = Qnil; | 488 |
488 } | 489 Now the idea is to dynamically adjust the array of GCPROed objects to |
489 #endif | 490 include only the "active" region of the stack. |
491 | |
492 We use the "GCPRO1 the array base and set the nvars member" method. It | |
493 would be slightly inefficient but correct to use GCPRO1_ARRAY here. It | |
494 would just redundantly set nvars. | |
495 #### Maybe it would be clearer to use GCPRO1_ARRAY and do GCPRO_STACK | |
496 after the switch? | |
497 | |
498 GCPRO_STACK is something of a misnomer, because it suggests that a | |
499 struct gcpro is initialized each time. This is false; only the nvars | |
500 member of a single struct gcpro is being adjusted. This works because | |
501 each time a new object is assigned to a stack location, the old object | |
502 loses its reference and is effectively UNGCPROed, and the new object is | |
503 automatically GCPROed as long as nvars is correct. Only when we | |
504 return from the interpreter do we need to finalize the struct gcpro | |
505 itself, and that's done at case Breturn. | |
506 */ | |
490 GCPRO1 (stack_ptr[1]); | 507 GCPRO1 (stack_ptr[1]); |
491 #if STATIC_GCPRO_STACK | |
492 gcpro1.nvars = stack_depth; | |
493 #endif | |
494 | 508 |
495 while (1) | 509 while (1) |
496 { | 510 { |
497 REGISTER Opcode opcode = (Opcode) READ_UINT_1; | 511 REGISTER Opcode opcode = (Opcode) READ_UINT_1; |
512 | |
513 GCPRO_STACK; /* Get nvars right before maybe signaling. */ | |
498 #ifdef ERROR_CHECK_BYTE_CODE | 514 #ifdef ERROR_CHECK_BYTE_CODE |
499 if (stack_ptr > stack_end) | 515 if (stack_ptr > stack_end) |
500 stack_overflow ("byte code stack overflow", Qunbound); | 516 stack_overflow ("byte code stack overflow", Qunbound); |
501 if (stack_ptr < stack_beg) | 517 if (stack_ptr < stack_beg) |
502 stack_overflow ("byte code stack underflow", Qunbound); | 518 stack_overflow ("byte code stack underflow", Qunbound); |
506 prev_opcode = this_opcode; | 522 prev_opcode = this_opcode; |
507 this_opcode = opcode; | 523 this_opcode = opcode; |
508 meter_code (prev_opcode, this_opcode); | 524 meter_code (prev_opcode, this_opcode); |
509 #endif | 525 #endif |
510 | 526 |
511 #if !STATIC_GCPRO_STACK | |
512 GCPRO_STACK; | |
513 #endif | |
514 switch (opcode) | 527 switch (opcode) |
515 { | 528 { |
516 REGISTER int n; | 529 REGISTER int n; |
517 | 530 |
518 default: | 531 default: |
537 do_varref: | 550 do_varref: |
538 { | 551 { |
539 Lisp_Object symbol = constants_data[n]; | 552 Lisp_Object symbol = constants_data[n]; |
540 Lisp_Object value = XSYMBOL (symbol)->value; | 553 Lisp_Object value = XSYMBOL (symbol)->value; |
541 if (SYMBOL_VALUE_MAGIC_P (value)) | 554 if (SYMBOL_VALUE_MAGIC_P (value)) |
555 /* I GCPRO_STACKed Fsymbol_value elsewhere, but I dunno why. */ | |
556 /* GCPRO_STACK; */ | |
542 value = Fsymbol_value (symbol); | 557 value = Fsymbol_value (symbol); |
543 PUSH (value); | 558 PUSH (value); |
544 break; | 559 break; |
545 } | 560 } |
546 | 561 |
614 case Bcall+5: | 629 case Bcall+5: |
615 case Bcall+6: | 630 case Bcall+6: |
616 case Bcall+7: | 631 case Bcall+7: |
617 n = (opcode < Bcall+6 ? opcode - Bcall : | 632 n = (opcode < Bcall+6 ? opcode - Bcall : |
618 opcode == Bcall+6 ? READ_UINT_1 : READ_UINT_2); | 633 opcode == Bcall+6 ? READ_UINT_1 : READ_UINT_2); |
634 /* #### Shouldn't this be just before the Ffuncall? | |
635 Neither Fget nor Fput can GC. */ | |
619 /* GCPRO_STACK; */ | 636 /* GCPRO_STACK; */ |
620 DISCARD (n); | 637 DISCARD (n); |
621 #ifdef BYTE_CODE_METER | 638 #ifdef BYTE_CODE_METER |
622 if (byte_metering_on && SYMBOLP (TOP)) | 639 if (byte_metering_on && SYMBOLP (TOP)) |
623 { | 640 { |
743 case Bconstant2: | 760 case Bconstant2: |
744 PUSH (constants_data[READ_UINT_2]); | 761 PUSH (constants_data[READ_UINT_2]); |
745 break; | 762 break; |
746 | 763 |
747 case Bcar: | 764 case Bcar: |
765 /* Fcar can GC via wrong_type_argument. */ | |
766 /* GCPRO_STACK; */ | |
748 TOP = CONSP (TOP) ? XCAR (TOP) : Fcar (TOP); | 767 TOP = CONSP (TOP) ? XCAR (TOP) : Fcar (TOP); |
749 break; | 768 break; |
750 | 769 |
751 case Bcdr: | 770 case Bcdr: |
771 /* Fcdr can GC via wrong_type_argument. */ | |
772 /* GCPRO_STACK; */ | |
752 TOP = CONSP (TOP) ? XCDR (TOP) : Fcdr (TOP); | 773 TOP = CONSP (TOP) ? XCDR (TOP) : Fcdr (TOP); |
753 break; | 774 break; |
754 | 775 |
755 | 776 |
756 case Bunbind_all: | 777 case Bunbind_all: |
760 break; | 781 break; |
761 | 782 |
762 case Bnth: | 783 case Bnth: |
763 { | 784 { |
764 Lisp_Object arg = POP; | 785 Lisp_Object arg = POP; |
786 /* Fcar and Fnthcdr can GC via wrong_type_argument. */ | |
787 /* GCPRO_STACK; */ | |
765 TOP = Fcar (Fnthcdr (TOP, arg)); | 788 TOP = Fcar (Fnthcdr (TOP, arg)); |
766 break; | 789 break; |
767 } | 790 } |
768 | 791 |
769 case Bsymbolp: | 792 case Bsymbolp: |
846 case BconcatN: | 869 case BconcatN: |
847 /* common case */ | 870 /* common case */ |
848 n = READ_UINT_1; | 871 n = READ_UINT_1; |
849 do_concat: | 872 do_concat: |
850 DISCARD (n - 1); | 873 DISCARD (n - 1); |
874 /* Apparently `concat' can GC; Fconcat GCPROs its arguments. */ | |
875 /* GCPRO_STACK; */ | |
851 TOP = Fconcat (n, &TOP); | 876 TOP = Fconcat (n, &TOP); |
852 break; | 877 break; |
853 | 878 |
854 | 879 |
855 case Blength: | 880 case Blength: |
863 TOP = Faset (TOP, arg1, arg2); | 888 TOP = Faset (TOP, arg1, arg2); |
864 break; | 889 break; |
865 } | 890 } |
866 | 891 |
867 case Bsymbol_value: | 892 case Bsymbol_value: |
893 /* Why does this need GCPRO_STACK? If not, remove others, too. */ | |
868 /* GCPRO_STACK; */ | 894 /* GCPRO_STACK; */ |
869 TOP = Fsymbol_value (TOP); | 895 TOP = Fsymbol_value (TOP); |
870 break; | 896 break; |
871 | 897 |
872 case Bsymbol_function: | 898 case Bsymbol_function: |
929 TOP = bytecode_negate (TOP); | 955 TOP = bytecode_negate (TOP); |
930 break; | 956 break; |
931 | 957 |
932 case Bnconc: | 958 case Bnconc: |
933 DISCARD (1); | 959 DISCARD (1); |
960 /* nconc2 GCPROs before calling this. */ | |
961 /* GCPRO_STACK; */ | |
934 TOP = bytecode_nconc2 (&TOP); | 962 TOP = bytecode_nconc2 (&TOP); |
935 break; | 963 break; |
936 | 964 |
937 case Bplus: | 965 case Bplus: |
938 { | 966 { |
967 case Bpoint: | 995 case Bpoint: |
968 PUSH (make_int (BUF_PT (current_buffer))); | 996 PUSH (make_int (BUF_PT (current_buffer))); |
969 break; | 997 break; |
970 | 998 |
971 case Binsert: | 999 case Binsert: |
1000 /* Says it can GC. */ | |
1001 /* GCPRO_STACK; */ | |
972 TOP = Finsert (1, &TOP); | 1002 TOP = Finsert (1, &TOP); |
973 break; | 1003 break; |
974 | 1004 |
975 case BinsertN: | 1005 case BinsertN: |
976 n = READ_UINT_1; | 1006 n = READ_UINT_1; |
977 DISCARD (n - 1); | 1007 DISCARD (n - 1); |
1008 /* See Binsert. */ | |
1009 /* GCPRO_STACK; */ | |
978 TOP = Finsert (n, &TOP); | 1010 TOP = Finsert (n, &TOP); |
979 break; | 1011 break; |
980 | 1012 |
981 case Baref: | 1013 case Baref: |
982 { | 1014 { |
1002 } | 1034 } |
1003 | 1035 |
1004 case Bequal: | 1036 case Bequal: |
1005 { | 1037 { |
1006 Lisp_Object arg = POP; | 1038 Lisp_Object arg = POP; |
1039 /* Can QUIT, so can GC, right? */ | |
1040 /* GCPRO_STACK; */ | |
1007 TOP = Fequal (TOP, arg); | 1041 TOP = Fequal (TOP, arg); |
1008 break; | 1042 break; |
1009 } | 1043 } |
1010 | 1044 |
1011 case Bnthcdr: | 1045 case Bnthcdr: |
1023 } | 1057 } |
1024 | 1058 |
1025 case Bmember: | 1059 case Bmember: |
1026 { | 1060 { |
1027 Lisp_Object arg = POP; | 1061 Lisp_Object arg = POP; |
1062 /* Can QUIT, so can GC, right? */ | |
1063 /* GCPRO_STACK; */ | |
1028 TOP = Fmember (TOP, arg); | 1064 TOP = Fmember (TOP, arg); |
1029 break; | 1065 break; |
1030 } | 1066 } |
1031 | 1067 |
1032 case Bgoto_char: | 1068 case Bgoto_char: |
1057 break; | 1093 break; |
1058 | 1094 |
1059 case Bskip_chars_forward: | 1095 case Bskip_chars_forward: |
1060 { | 1096 { |
1061 Lisp_Object arg = POP; | 1097 Lisp_Object arg = POP; |
1098 /* Can QUIT, so can GC, right? */ | |
1099 /* GCPRO_STACK; */ | |
1062 TOP = Fskip_chars_forward (TOP, arg, Qnil); | 1100 TOP = Fskip_chars_forward (TOP, arg, Qnil); |
1063 break; | 1101 break; |
1064 } | 1102 } |
1065 | 1103 |
1066 case Bassq: | 1104 case Bassq: |