diff options
| author | Chong Yidong | 2009-03-12 01:52:59 +0000 |
|---|---|---|
| committer | Chong Yidong | 2009-03-12 01:52:59 +0000 |
| commit | c36745c6e454890ac3dbe0b70532f6215aa4fb51 (patch) | |
| tree | 2c35867d925fd9aa3664df2fa82bc845fcbcd7b4 | |
| parent | cf4229eb0aa9b33c390735ed5a5b2d16dce720e0 (diff) | |
| download | emacs-c36745c6e454890ac3dbe0b70532f6215aa4fb51.tar.gz emacs-c36745c6e454890ac3dbe0b70532f6215aa4fb51.zip | |
(Speed of Byte-Code): Update example.
(Disassembly): Update examples.
| -rw-r--r-- | doc/lispref/compile.texi | 173 |
1 files changed, 40 insertions, 133 deletions
diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 01908176efb..227f86f930c 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi | |||
| @@ -72,9 +72,9 @@ Here is an example: | |||
| 72 | @end group | 72 | @end group |
| 73 | 73 | ||
| 74 | @group | 74 | @group |
| 75 | (silly-loop 100000) | 75 | (silly-loop 50000000) |
| 76 | @result{} ("Fri Mar 18 17:25:57 1994" | 76 | @result{} ("Wed Mar 11 21:10:19 2009" |
| 77 | "Fri Mar 18 17:26:28 1994") ; @r{31 seconds} | 77 | "Wed Mar 11 21:10:41 2009") ; @r{22 seconds} |
| 78 | @end group | 78 | @end group |
| 79 | 79 | ||
| 80 | @group | 80 | @group |
| @@ -83,13 +83,13 @@ Here is an example: | |||
| 83 | @end group | 83 | @end group |
| 84 | 84 | ||
| 85 | @group | 85 | @group |
| 86 | (silly-loop 100000) | 86 | (silly-loop 50000000) |
| 87 | @result{} ("Fri Mar 18 17:26:52 1994" | 87 | @result{} ("Wed Mar 11 21:12:26 2009" |
| 88 | "Fri Mar 18 17:26:58 1994") ; @r{6 seconds} | 88 | "Wed Mar 11 21:12:32 2009") ; @r{6 seconds} |
| 89 | @end group | 89 | @end group |
| 90 | @end example | 90 | @end example |
| 91 | 91 | ||
| 92 | In this example, the interpreted code required 31 seconds to run, | 92 | In this example, the interpreted code required 22 seconds to run, |
| 93 | whereas the byte-compiled code required 6 seconds. These results are | 93 | whereas the byte-compiled code required 6 seconds. These results are |
| 94 | representative, but actual results will vary greatly. | 94 | representative, but actual results will vary greatly. |
| 95 | 95 | ||
| @@ -619,10 +619,10 @@ elements. | |||
| 619 | @section Disassembled Byte-Code | 619 | @section Disassembled Byte-Code |
| 620 | @cindex disassembled byte-code | 620 | @cindex disassembled byte-code |
| 621 | 621 | ||
| 622 | People do not write byte-code; that job is left to the byte compiler. | 622 | People do not write byte-code; that job is left to the byte |
| 623 | But we provide a disassembler to satisfy a cat-like curiosity. The | 623 | compiler. But we provide a disassembler to satisfy a cat-like |
| 624 | disassembler converts the byte-compiled code into humanly readable | 624 | curiosity. The disassembler converts the byte-compiled code into |
| 625 | form. | 625 | human-readable form. |
| 626 | 626 | ||
| 627 | The byte-code interpreter is implemented as a simple stack machine. | 627 | The byte-code interpreter is implemented as a simple stack machine. |
| 628 | It pushes values onto a stack of its own, then pops them off to use them | 628 | It pushes values onto a stack of its own, then pops them off to use them |
| @@ -650,9 +650,6 @@ compiles it and disassembles the resulting compiled code. | |||
| 650 | Here are two examples of using the @code{disassemble} function. We | 650 | Here are two examples of using the @code{disassemble} function. We |
| 651 | have added explanatory comments to help you relate the byte-code to the | 651 | have added explanatory comments to help you relate the byte-code to the |
| 652 | Lisp source; these do not appear in the output of @code{disassemble}. | 652 | Lisp source; these do not appear in the output of @code{disassemble}. |
| 653 | These examples show unoptimized byte-code. Nowadays byte-code is | ||
| 654 | usually optimized, but we did not want to rewrite these examples, since | ||
| 655 | they still serve their purpose. | ||
| 656 | 653 | ||
| 657 | @example | 654 | @example |
| 658 | @group | 655 | @group |
| @@ -676,84 +673,41 @@ they still serve their purpose. | |||
| 676 | @end group | 673 | @end group |
| 677 | 674 | ||
| 678 | @group | 675 | @group |
| 679 | 0 constant 1 ; @r{Push 1 onto stack.} | 676 | 0 varref integer ; @r{Get the value of @code{integer}} |
| 680 | 677 | ; @r{and push it onto the stack.} | |
| 681 | 1 varref integer ; @r{Get value of @code{integer}} | 678 | 1 constant 1 ; @r{Push 1 onto stack.} |
| 682 | ; @r{from the environment} | ||
| 683 | ; @r{and push the value} | ||
| 684 | ; @r{onto the stack.} | ||
| 685 | @end group | 679 | @end group |
| 686 | 680 | ||
| 687 | @group | 681 | @group |
| 688 | 2 eqlsign ; @r{Pop top two values off stack,} | 682 | 2 eqlsign ; @r{Pop top two values off stack, compare} |
| 689 | ; @r{compare them,} | 683 | ; @r{them, and push result onto stack.} |
| 690 | ; @r{and push result onto stack.} | ||
| 691 | @end group | 684 | @end group |
| 692 | 685 | ||
| 693 | @group | 686 | @group |
| 694 | 3 goto-if-nil 10 ; @r{Pop and test top of stack;} | 687 | 3 goto-if-nil 1 ; @r{Pop and test top of stack;} |
| 695 | ; @r{if @code{nil}, go to 10,} | 688 | ; @r{if @code{nil}, go to 1,} |
| 696 | ; @r{else continue.} | 689 | ; @r{else continue.} |
| 697 | @end group | ||
| 698 | |||
| 699 | @group | ||
| 700 | 6 constant 1 ; @r{Push 1 onto top of stack.} | 690 | 6 constant 1 ; @r{Push 1 onto top of stack.} |
| 701 | 691 | 7 return ; @r{Return the top element} | |
| 702 | 7 goto 17 ; @r{Go to 17 (in this case, 1 will be} | 692 | ; @r{of the stack.} |
| 703 | ; @r{returned by the function).} | ||
| 704 | @end group | ||
| 705 | |||
| 706 | @group | ||
| 707 | 10 constant * ; @r{Push symbol @code{*} onto stack.} | ||
| 708 | |||
| 709 | 11 varref integer ; @r{Push value of @code{integer} onto stack.} | ||
| 710 | @end group | 693 | @end group |
| 711 | 694 | ||
| 712 | @group | 695 | @group |
| 713 | 12 constant factorial ; @r{Push @code{factorial} onto stack.} | 696 | 8:1 varref integer ; @r{Push value of @code{integer} onto stack.} |
| 714 | 697 | 9 constant factorial ; @r{Push @code{factorial} onto stack.} | |
| 715 | 13 varref integer ; @r{Push value of @code{integer} onto stack.} | 698 | 10 varref integer ; @r{Push value of @code{integer} onto stack.} |
| 716 | 699 | 11 sub1 ; @r{Pop @code{integer}, decrement value,} | |
| 717 | 14 sub1 ; @r{Pop @code{integer}, decrement value,} | ||
| 718 | ; @r{push new value onto stack.} | 700 | ; @r{push new value onto stack.} |
| 719 | @end group | 701 | 12 call 1 ; @r{Call function @code{factorial} using} |
| 720 | |||
| 721 | @group | ||
| 722 | ; @r{Stack now contains:} | ||
| 723 | ; @minus{} @r{decremented value of @code{integer}} | ||
| 724 | ; @minus{} @r{@code{factorial}} | ||
| 725 | ; @minus{} @r{value of @code{integer}} | ||
| 726 | ; @minus{} @r{@code{*}} | ||
| 727 | @end group | ||
| 728 | |||
| 729 | @group | ||
| 730 | 15 call 1 ; @r{Call function @code{factorial} using} | ||
| 731 | ; @r{the first (i.e., the top) element} | 702 | ; @r{the first (i.e., the top) element} |
| 732 | ; @r{of the stack as the argument;} | 703 | ; @r{of the stack as the argument;} |
| 733 | ; @r{push returned value onto stack.} | 704 | ; @r{push returned value onto stack.} |
| 734 | @end group | 705 | @end group |
| 735 | 706 | ||
| 736 | @group | 707 | @group |
| 737 | ; @r{Stack now contains:} | 708 | 13 mult ; @r{Pop top two values off stack, multiply} |
| 738 | ; @minus{} @r{result of recursive} | 709 | ; @r{them, and push result onto stack.} |
| 739 | ; @r{call to @code{factorial}} | 710 | 14 return ; @r{Return the top element of stack.} |
| 740 | ; @minus{} @r{value of @code{integer}} | ||
| 741 | ; @minus{} @r{@code{*}} | ||
| 742 | @end group | ||
| 743 | |||
| 744 | @group | ||
| 745 | 16 call 2 ; @r{Using the first two} | ||
| 746 | ; @r{(i.e., the top two)} | ||
| 747 | ; @r{elements of the stack} | ||
| 748 | ; @r{as arguments,} | ||
| 749 | ; @r{call the function @code{*},} | ||
| 750 | ; @r{pushing the result onto the stack.} | ||
| 751 | @end group | ||
| 752 | |||
| 753 | @group | ||
| 754 | 17 return ; @r{Return the top element} | ||
| 755 | ; @r{of the stack.} | ||
| 756 | @result{} nil | ||
| 757 | @end group | 711 | @end group |
| 758 | @end example | 712 | @end example |
| 759 | 713 | ||
| @@ -783,8 +737,8 @@ The @code{silly-loop} function is somewhat more complex: | |||
| 783 | 737 | ||
| 784 | @group | 738 | @group |
| 785 | 1 call 0 ; @r{Call @code{current-time-string}} | 739 | 1 call 0 ; @r{Call @code{current-time-string}} |
| 786 | ; @r{ with no argument,} | 740 | ; @r{with no argument,} |
| 787 | ; @r{ pushing result onto stack.} | 741 | ; @r{pushing result onto stack.} |
| 788 | @end group | 742 | @end group |
| 789 | 743 | ||
| 790 | @group | 744 | @group |
| @@ -793,12 +747,9 @@ The @code{silly-loop} function is somewhat more complex: | |||
| 793 | @end group | 747 | @end group |
| 794 | 748 | ||
| 795 | @group | 749 | @group |
| 796 | 3 varref n ; @r{Get value of @code{n} from} | 750 | 3:1 varref n ; @r{Get value of @code{n} from} |
| 797 | ; @r{the environment and push} | 751 | ; @r{the environment and push} |
| 798 | ; @r{the value onto the stack.} | 752 | ; @r{the value onto the stack.} |
| 799 | @end group | ||
| 800 | |||
| 801 | @group | ||
| 802 | 4 sub1 ; @r{Subtract 1 from top of stack.} | 753 | 4 sub1 ; @r{Subtract 1 from top of stack.} |
| 803 | @end group | 754 | @end group |
| 804 | 755 | ||
| @@ -807,9 +758,6 @@ The @code{silly-loop} function is somewhat more complex: | |||
| 807 | ; @r{i.e., copy the top of} | 758 | ; @r{i.e., copy the top of} |
| 808 | ; @r{the stack and push the} | 759 | ; @r{the stack and push the} |
| 809 | ; @r{copy onto the stack.} | 760 | ; @r{copy onto the stack.} |
| 810 | @end group | ||
| 811 | |||
| 812 | @group | ||
| 813 | 6 varset n ; @r{Pop the top of the stack,} | 761 | 6 varset n ; @r{Pop the top of the stack,} |
| 814 | ; @r{and bind @code{n} to the value.} | 762 | ; @r{and bind @code{n} to the value.} |
| 815 | 763 | ||
| @@ -821,71 +769,30 @@ The @code{silly-loop} function is somewhat more complex: | |||
| 821 | 769 | ||
| 822 | @group | 770 | @group |
| 823 | 7 constant 0 ; @r{Push 0 onto stack.} | 771 | 7 constant 0 ; @r{Push 0 onto stack.} |
| 824 | @end group | ||
| 825 | |||
| 826 | @group | ||
| 827 | 8 gtr ; @r{Pop top two values off stack,} | 772 | 8 gtr ; @r{Pop top two values off stack,} |
| 828 | ; @r{test if @var{n} is greater than 0} | 773 | ; @r{test if @var{n} is greater than 0} |
| 829 | ; @r{and push result onto stack.} | 774 | ; @r{and push result onto stack.} |
| 830 | @end group | 775 | @end group |
| 831 | 776 | ||
| 832 | @group | 777 | @group |
| 833 | 9 goto-if-nil-else-pop 17 ; @r{Goto 17 if @code{n} <= 0} | 778 | 9 goto-if-not-nil 1 ; @r{Goto 1 if @code{n} > 0} |
| 834 | ; @r{(this exits the while loop).} | 779 | ; @r{(this continues the while loop)} |
| 835 | ; @r{else pop top of stack} | 780 | ; @r{else continue.} |
| 836 | ; @r{and continue} | ||
| 837 | @end group | ||
| 838 | |||
| 839 | @group | ||
| 840 | 12 constant nil ; @r{Push @code{nil} onto stack} | ||
| 841 | ; @r{(this is the body of the loop).} | ||
| 842 | @end group | ||
| 843 | |||
| 844 | @group | ||
| 845 | 13 discard ; @r{Discard result of the body} | ||
| 846 | ; @r{of the loop (a while loop} | ||
| 847 | ; @r{is always evaluated for} | ||
| 848 | ; @r{its side effects).} | ||
| 849 | @end group | ||
| 850 | |||
| 851 | @group | ||
| 852 | 14 goto 3 ; @r{Jump back to beginning} | ||
| 853 | ; @r{of while loop.} | ||
| 854 | @end group | ||
| 855 | |||
| 856 | @group | ||
| 857 | 17 discard ; @r{Discard result of while loop} | ||
| 858 | ; @r{by popping top of stack.} | ||
| 859 | ; @r{This result is the value @code{nil} that} | ||
| 860 | ; @r{was not popped by the goto at 9.} | ||
| 861 | @end group | ||
| 862 | |||
| 863 | @group | ||
| 864 | 18 varref t1 ; @r{Push value of @code{t1} onto stack.} | ||
| 865 | @end group | 781 | @end group |
| 866 | 782 | ||
| 867 | @group | 783 | @group |
| 868 | 19 constant current-time-string ; @r{Push} | 784 | 12 varref t1 ; @r{Push value of @code{t1} onto stack.} |
| 869 | ; @r{@code{current-time-string}} | 785 | 13 constant current-time-string ; @r{Push @code{current-time-string}} |
| 870 | ; @r{onto top of stack.} | 786 | ; @r{onto top of stack.} |
| 787 | 14 call 0 ; @r{Call @code{current-time-string} again.} | ||
| 871 | @end group | 788 | @end group |
| 872 | 789 | ||
| 873 | @group | 790 | @group |
| 874 | 20 call 0 ; @r{Call @code{current-time-string} again.} | 791 | 15 unbind 1 ; @r{Unbind @code{t1} in local environment.} |
| 875 | @end group | 792 | 16 list2 ; @r{Pop top two elements off stack,} |
| 876 | |||
| 877 | @group | ||
| 878 | 21 list2 ; @r{Pop top two elements off stack,} | ||
| 879 | ; @r{create a list of them,} | 793 | ; @r{create a list of them,} |
| 880 | ; @r{and push list onto stack.} | 794 | ; @r{and push list onto stack.} |
| 881 | @end group | 795 | 17 return ; @r{Return value of the top of stack.} |
| 882 | |||
| 883 | @group | ||
| 884 | 22 unbind 1 ; @r{Unbind @code{t1} in local environment.} | ||
| 885 | |||
| 886 | 23 return ; @r{Return value of the top of stack.} | ||
| 887 | |||
| 888 | @result{} nil | ||
| 889 | @end group | 796 | @end group |
| 890 | @end example | 797 | @end example |
| 891 | 798 | ||