1 LISP LIBRARY PACKAGES MANUAL 1 LISP LIBRARY PACKAGES MANUAL SPY 1 PROGRAM ANALYSIS 1 SPY 6 Spy is a tool to help you make programs run faster. It gives you a picture of where the program is spending its time. Spy has two parts: a ©©sampler'' that you run while running your program, which monitors what the program is doing, and a ©©displayer'' that displays the data gathered by the sampler. The "sampler'' periodically interrupts the running program to account the functions in the current call stack. This allows Spy to remember not only (proportionally) how long is spent in each individual function, but also how long each function is seen on the call stack. The sampler data structures were designed to minimize interference with the normal running of the programÿÿï%ÿthere is little noticable performance degradation. Because Spy doesn't log every call and return, you can run it even over long computations, unlike PCallStats. The "displayer'' uses the Grapher package to display the data gathered by the sampler. In the graph, the height of each node is adjusted to be proportional to the amount of time. Just as Masterscope and Browser give an interactive picture of the static structure of the program, Spy gives an interactive picture of the dynamic structure. The displayer is interactive as well as graphical. That is, you can look at the data in a variety of ways, since it seems there is no one picture that says it all. Since the displayer knows the whole call graph, it can show the entire tree structure (with separate calls to a function accounted separately) or merging separate calls to the same functions. Since the sampler records the entire calling stack when it samples, it can account for both individual and cumulative time. When the sampler runs, if a function is on the top of the stack, it adds to its individual total; if the function is on the stack at all, the sampler adds to the cumulative total. When there are several calls to the same function within the graph, the displayer can either ©©merge'' the nodes (show the total time for the function in one node) or not. If a node is merged, then one of the boxes in the graph will have all of the time for that function accounted to it, and the rest will be left as ©©ghost'' boxes. Spy has a variety of ways of controlling which nodes will be merged. 2 How to Use SPY 1 (SPY.BUTTON) [Function] This function puts up a little window, which you can use to turn Spy on and off. When Spy isn't watching, it looks like this: @CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÇÏÌ0ŽCÌll0Ìlf`Ï f`ϾÇÌcÀ fÁïÁ€ fÌl€ fÌl€ f£Ìl€ fÇÌ€Æ#ÀCÀÀÀ•ú£È ÿè€À¿ÿn¨CÈ‚¾õ #ÀTýҗꀓÀ‚þ­UµÅ?í¢ ÿ#SÀ¿ú¨Qÿ„£Ëþ¤éSÇý¨ߥ#Æò@ õÓÇôHísËÈ@þÓÇЂ%ksʤ(žÓÏAD_sÀºý²U³Ê¥.É _sľûþ„A&“Â+oÿ@VÓÉYWä £ÅlÄwre#Ê ø@SÅQiR£ÈLPCÍE èJ„£Â“` È ´IÉSÄ”¨´ “À@DE+RCÂõ@#Â�~€CÈ õ°DDGú Â ?F"CÅP‚‘^°ÂÈ$DþCËtŠ©z‚Âò%7ü CÁÍ·øÀwþïà€À›»¿Ê£ÀFûÿÀ}ÔCÈ‚­,#ÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Pushing it once will turn on sampling, and the window will look like this: @CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÇÏÌ0Ìll0Ìlf`Ï f`ÏÀÇÌcÀ l`ÁïÁ€ l`Ìl€ l`Ìl€ l`Ìl€ l`ÇÌ€Ì`ÀÀÀÀ•ú£È ÿè€À¿ÿn¨CÈ‚¾õ #ÀTýҗꀓÀ‚þ­UµÅ?í¢ ÿ£SÀ¿ú¨Qþ„£Ëþ¤éSÇý¨ߥ#Æò@ õÓÇôHísËÈ@þÓÇЂ%ksʤ(žÓÏAD_sÀºý²U³Ê¥.É _sľûþ„A&“Â+oý@VÓÉYUô £Ål«·Re#Ê/øè@SÅUOëZR£È ÿÿùRCÍDÿÿÔ‰R£Â¿ÿî È+ÿÿ«‚SÄŒ½}þ “À]/úÿû‚C´_úþ #¹/ø_ÿ€CÈäê/¤AÂðMtWõ Á& ,CÀP“Ñ_¤€Â@�CÈA BVˆÀ€”” CÁ À@ À€@£À@ÀCÈ€ #ÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Pushing it again will turn off sampling, and display the results (SPY.TREE 10). This is the simplest way of spying on operations. (Note that you can't turn off sampling if the mouse process is locked out.) Alternatively, you can turn Spying on and off by using the following functions: (SPY.START) [Function] Reinitializes the internal Spy data structures, and turns on sampling. (SPY.END) [Function] Turns off sampling, and cleans up the data structures. (SPY.TOGGLE) [Function] If Spying is off, turn it on with (SPY.START). If it's on, turn it off with (SPY.END) and then show the results with (SPY.TREE 10). It's reasonable to use this as an interrupt character, e.g., (INTERRUPTCHAR (CHARCODE ^C) '(SPY.TOGGLE) T) will enable control-C as an interrupt which will turn spying on and off same as pushing the spy button. (WITH.SPY form) [Macro] Calls (SPY.START), evaluates form, calls (SPY.END), and then returns the value of form. For example, (WITH.SPY (LOAD 'FOO)) is basically (PROGN (SPY.START) (PROG1 (LOAD 'FOO) (SPY.END]. To display the results, call the function SPY.TREE: (SPY.TREE threshold individualp mergetype depthlimit) [Function] SPY.TREE displays the results of the last ©©spy'' in a grapher window. There are a number of parameters that control the display, which you can either set when you call SPY.TREE, or set interactively with the menu. I normally just use (SPY.TREE) and use the menus. threshold is a number (defaults to 0), individualp is either NIL or T, mergetype is one of (NONE, ALL, DEFAULT), and depthlimit is a number (defaults to NIL = arbitrary depth; not completely debugged for other values). You will get a prompt to lay down a window, and then a graph will appear in it, something like this: ÿ•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþŽßÿxã·ÿÿÿÿ¿ÿø?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþu_üw]Wüí¤ÛsÙÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþu?ÿw]Oûm’Ûm¶¶Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþv¯ÿw]«ûí¶Ûq¶°þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþwWÿw]Õûi¶Óm·wþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ�VxãÕüå¶Ëb—xÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþïÿÿ»ÿÿÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÀ€À€ÀˆÀCî�¸qŒóÀ™ @„Ü$ JR„¤Àˆ „ü$ JP„ Àˆ@ „¯8rPãÿÿÿæˆ „¬(RP€„Àÿÿÿüÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿ€‰ „Œ$ˆJR„¤Àÿÿÿüÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿ€ œÀŽ�¤ˆIŒóÀ€ 0000€ €À€ 0000€€À€ 0000€€À€ 0000€!ÿÿÿÿÿÿÿÿÿÿÿÀ€ 0000€!ÿÿÿÿÿÿÿÿÿÿÿÀ€ 0000€@€ 0000€€€ 0000€€€ 0000€€ 0000€€ 0000€€ 0000€€ 0000€ÿÿÿÿÿÿÿÿÿÿÿÀ€ 0000€ÿÿÿÿÿÿÿÿÿÿÿÀ€ 0000€€À€ 0000€€À€ 0000€€À€ 0000€ €À&€ 0000€ €ÀÆ€ 0000€@€À€ 0000€@€Àà€ 0000€€˜ÀB,“<qŒóÀ€ 0000€€¥ Cr”  JR„¤Àð€ 0000€„ #ò” JP„ Ï€ 0000€ˆ@"²“8rPãð€ 0000€� ²� RP€„Ï€ 0000€¡ 2” ˆJR„¤Àð€ 0000€!¼À ,c<ˆIŒóÀ€ 0000€A€Àà€ 0000€�€À€ 0000€€ÀÆ€ 0000€ €À&€ 0000€ €À€ 0000€@€À€ 0000€@ €À€ 0000€€@ÿÿÿÿÿÿÿÿÿÿÿÀ€ 0000€�€ÿÿÿÿÿÿÿÿÿÿÿÀ€ 0000�€ 0000�€ 0000‚€ 0000„€ 0000„`€ 0000ˆ€€ 0000‰€ 0000’ˆÆì F0‰%àsŒg˜Æ01À{œgï°1ÀCÑ$<ÎE”™)Œ ÉHÚ©JR”%)03% BR”¥03% BT!)m¸‰kŒ KXú±JR„! 01-`BR”¡01-`"T!)} ‰­�ÿÿÿüMhª±Às’‡Í7ÿÿÿñ5 sœ—Â7ÿÿÿñ5 #›T9.Uàÿÿÿÿÿÿÿÿÿÿÿÿÿÿæ‰)Œ IH¯éB’„)01% B”•01%  ü!*U¸ÿÿÿÿÿÿÿÿÿÿÿÿÿÿæ‰)Œ IHŒeBR”%)01% BR”¥01% Œ!)E¦€fœÆŒ æ0ŒcäBLg˜Æ03˜ÀzRd™â03˜À Ä� ÉE‘€€f€ 0000�`€f€ 0000ˆ€f€ 0000ˆ€f€ 0000„€€f€ 0000‚`€f€ 0000‚€f€ 0000�€f€ 0000��˜ÀC„d™ÆJ\8ÆyŒf€ 0000€€a¥ BJ•%)KR¥)BRf€ 0000€€… "J†!)KÒ¥(Bf€ 0000€@ˆÀ#І-ÉKÒ9(qŒf€ 0000€ ‘ _…%IJÒ)(@Bf€ 0000€ ¡ Q”¥)JÒD%)BRf€ 0000€¼À ‘d]&2\D$ÆyŒf€ 0000€€f€ 0000€€f€ 0000€€f€ 0000€€f€ 0000€€f€ 0000€€f€ 0000€€f€ 0000€€f€ 0000€€€f€ 0000€€€f€ 0000€@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿæ€ 0000€@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿæ€ 0000€ € 0000€€ 0000€€ 0000€€ 0000€€ 0000€ÿÿÿÿÿÿþÿÿÿæ€ 0000€ÿÿÿÿÿÿþÿÿÿæ€ 0000€€€ 0000€€€ 0000€€€ 0000€�€€ 0000€�€€ 0000€A€€ 0000€A€€ 0000€!€€ 0000€€€ 0000€€€ 0000€ €€ 0000€ ˜@Cþã¾Æaæ€ 0000€¤À@�‘ &“Fÿÿÿüÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿ€„@ �‘&‚Fÿÿÿüÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿ€ˆ@ œ‘Fÿÿÿþ!‚f„@�‘†BF¤@�‘ ‘BF˜àžã‰æc€"f€ €€€€€€€€€€ÿÿÿÿÿÿþÿÿÿæÿÿÿÿÿÿþÿÿÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ In this display, 100% of the time was spent under the top four frames that a process normally has, T, \MAKE.PROCESS0, ERRORSET, \EVALFORM. (Spy should probably eliminate those from the display, but it doesn't right now). That time was then divided up among four processes: \TIMER.PROCESS, \MOUSE.PROCESS, \BACKGROUND.PROCESS, \TEDIT2. The numbers to the left of the label are the percentages. The height of the box is proportional to the percentage (except that it is always made big enough to hold the label). The width isn't significantÿÿï%ÿit is just wide enough to hold the name of the function. If you left-button any node, the window title will change to show the function name, and the individual and cumulative percentages; the first number is the individual total and the second is the cumulative. If you middle-button the node, you will get a menu with two items: SubTree Creates another spy window that includes data only from this node and its descendents. Let's suppose that I was only interested in the actions that I had invoked via the mouse: I can middle-button \MOUSE.PROCESS and select the SubTree option. I then get a picture like this: ü€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðüvÿûÇ¿ÿÿÿûýÿÿß}ûއ xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðûªÿãºê¿çm&Û˜®Îï9½»vÿ»vöõû·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðû©ÿûºêÛl–Ûmµ¶ï9½»ž»öü<ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðûµûºí_ßm¶Û�µ‡÷U½»îÿ‡vöýÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðûº¿ûºî¯ÛM¶›m»¿ûU½»vÿ¿vöõû·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðüz³ûǯç-¶[»ÆûmÃÇŽ ¿w xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿ÷{ÿÿýßÿÿÿÿÿÿþÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÀ0À0À0Ïÿÿÿÿÿÿÿÿÿÿÿð0Ïÿÿÿÿÿÿÿÿÿÿÿð0Ì0?ÿÿÿÿÿ0Ì0?ÿÿÿÿÿ0Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì00ÿÿÿÿÿÿÿÿÿÿÿÿÿø0Ì00ÿÿÿÿÿÿÿÿÿÿÿÿÿø0Ì000Ì000Ì01ŒAŒ“€ƒ \‡™sÐdX0Ì02” BR£1€„¤ +R„%J”X0Ì02” BPÀD +Ò„%¸J”X0Ì0t¤BPÃÿÿÿ€E +Ò‡%¾s�•X0Ì0·þ BP£€$  ~Ò„$¨R•X0Ì00„ BR“€$¤‰FÒ„$èJ—Ø0Ì00„yŒ‹9À˜‰F\÷˜OJb˜0Ì000Ì000Ì0000Ì0@0ÿÿÿÿÿÿÿÿÿÿÿÿÿø0Ì0€0ÿÿÿÿÿÿÿÿÿÿÿÿÿø0Ì000Ì000Ì000Ì000Ì000Ì0 00Ì0@00Ì0€00Ì000Ì000Ì0 00Ì000Ì0 00Ì0@?ÿÿÿÿÿ0ÌF0‹$Ïœc<Æ0€?ÿÿÿÿÿ0ÌÉHÜ¥(R”¡)1?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿà0ÌKXü¥R”!2?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿà0ÌMh¬¤Îœ”8Æ40`0ÌIH¬¤(” !20`0ÌIHŒ¥("”¡)10`0Ìæ0‹Ï"c<Æ0€0`0Ì0@0`0Ì0 0`0Ì00`0Ì0 0`0Ì00`0Ì00`ˆˆˆˆˆˆˆˆˆˆ0Ì0€0`"""""""""""0Ì0@0` 0Ì0 0`0Ì00`0 ÷âÉ3Ìù?à0Ì00`)H�7)J"‰0Ì00`!�?)B"‰0Ì00`‚á+)3Œ"‰À0Ì00` �+) 'É0Ì0€0`p(@�#)J$I0Ì0@0`€/xñ"Æ3Ì$Iâ0Ì000`0Ì00``0Ì00`€ 0Ì07¼º\dAIž‰.CÜ`"""""""""""0Ì04 “R”A¹JP•©B`àˆˆˆˆˆˆˆˆˆˆ0Ì0·8“Ò”AùJ•éBgÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿ€0Ì0p„ “Ò•AYIœ•éCœxÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿ€0Ì00„ ’Ò•AYHP¿iBg` €0Ì04¤’Ò—ÑJPD£iB`à` €0Ì03:\b‘1žD£.{Ò`` €0Ì00`€` €0Ì00``` €0Ì00`` €0Ì00`€f0çÿ3þà ÎB, ÆÜã8Ï}€0Ì00`piH”¤HH��)B, )”¥(€0Ì00`a”¤H@��)B, !”¥€0Ì00`âç$N@œ�ÎAOÿÿÿüBœä¸Îÿÿÿÿ0Ì00`d …$H@��?@Œ „¤¨(€0Ì00`h@„¤HH�’#@Œ ”¥(€0Ì00`ox„˜O0žâ#xŒ ïÒ“$Ï€0Ì00`` €0Ì00`` €0Ì00`` €0Ì00`` €0Ì00`` €0Ì00`` €0Ì00`` €0Ì00`ÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿ€0Ì00`ÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿ€0Ì00`0Ïÿÿÿÿÿÿÿÿÿÿÿð0`0Ïÿÿÿÿÿÿÿÿÿÿÿð0`0À0`0À?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿà0À?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿà0À0À0À0À0À0À0À0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð Delete Removes the selected item from consideration in this window. For example, if you don't want to consider "BLOCK" in the graph at all, you can Delete the BLOCK box and get: ü€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðüvÿûÇ¿ÿÿÿûýÿÿß}ûއ xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðûªÿãºê¿çm&Û˜®Îï9½»vÿ»vöõû·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðû©ÿûºêÛl–Ûmµ¶ï9½»ž»öü<ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðûµûºí_ßm¶Û�µ‡÷U½»îÿ‡vöýÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðûº¿ûºî¯ÛM¶›m»¿ûU½»vÿ¿vöõû·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðüz³ûǯç-¶[»ÆûmÃÇŽ ¿w xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿ÷{ÿÿýßÿÿÿÿÿÿþÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÀ0À0À0À0À0À0À0Ïÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0Ïÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì00"""""""""" 0Ì00"""""""""" 0Ì000Ì000Ì00€g¿IžgÉÿ 0Ì00*@” ¹JP‘H 0Ì00*À„ ùJ�H0Ì00K@· YIœaN0Ì00~@” YHP>H 0Ì00b @” JP‘"H 0Ì00€ €w‰1ža"O0Ì000Ì00 0Ì00` 0Ì00€ˆˆˆˆˆˆˆˆˆˆ€0Ì00ˆˆˆˆˆˆˆˆˆˆ€0Ì00 ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿü0Ì000ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿü0Ì00À`` 0ÌF0‹$Ïœc<Æ01ÀEÒã"²Lð$Irã`` 0ÌÉHÜ¥(R”¡)03% D𔢠ÊR€$­J“ `` 0ÌKXü¥R”!01-`Dž”¢ÊP€$¯J“0`` 0ÌMh¬¤Îœ”8Æ7ÿÿÿñ5 Tž”ª ÊLà<¯Jã@`` 0ÌIH¬¤(” !01% T–”ª ÊB€%ûJ£0`` 0ÌIHŒ¥("”¡)01% |–”¾ˆÊR‚%J“ `` 0Ìæ0‹Ï"c<Æ03˜À)Ò㈱Œò%sÞ“`` 0Ì00À`` 0Ì000`` 0Ì00 `` 0Ì00`` 0Ì00À`` 0Ì000`` 0Ì00 `` 0Ì00€‡8ÏùŸ÷Nr`c0çÆ{ì0Ì00Ã*@„¥"BD„€©J`eH”¥)@Œ0Ì003*ÀD¥"B„€©J`eX”¥(@Œ0Ì00K@G9"r䀮r ÿÿÿéhç%Æp�ÿÿÿ0Ì00~@$)"B„�øB`oÈ¥%A@Œ0Ì00 @$%"BD„‘B`aH”¥)@Œ0Ì00 €$Ây„÷CÄ`a0”™&xŒ0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00`` 0Ì00ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿü0Ì00ÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿü0Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ì000Ïÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0Ïÿÿÿÿÿÿÿÿÿÿÿð?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0À0À0À0À0À0À0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð Edit Invokes the inspector on the function selected. (Usually, this will give you a choice of DisplayEdit, TtyEdit, and InspectCode.) If you press the middle button while not on a node, you will get a menu that will let you change the parameters for this window: SetThreshold Sets the threshold for displaying a node. Any node whose percentage is below the threshold won't show up (unless it is needed to connect the graph together). You can set the initial threshold via the threshold argument to SPY.TREE; otherwise it defaults to zero. Individual/Cumulative This is used to toggle between the display of Individual times and Cumulative. The initial default is Cumulative; you can set it to Individual by supplying T as the INDIVIDUALP argument to SPY.TREE. (See below). MergeNone/MergeAll/MergeDefault This controls merging of nodes. See discussion below. 2 Merging 1 If two nodes are merged, then the merged node will include the time (and descendents) of the other. The display of a ©©merged'' node is differentÿÿï%ÿit is shown with a thick gray border, e.g. }UUUUUUUUUUUUUUUPªªªªªªªªªªªªªªª¨UUUUUUUUUUUUUUUPªªªªªªªªªªªªªªª¨PP (S€@€@P¡@ˆ€@(Q8ÂIÌpÎ3€çÆqŽP¡%"JR€$‰J@”…)JP(Q%J\`$‰r”(KŒP¡%"JP$©B”%)J(S¤Â9ÌàI2ä&IœP (PP (UUUUUUUUUUUUUUUPªªªªªªªªªªªªªªª¨UUUUUUUUUUUUUUUPªªªªªªªªªªªªªªª¨ The time in a ©©merged'' node is the sum of the times for all occurrences. Other calls to the same function may show up as ©©ghost'' boxes, e.g. Qˆˆˆˆˆˆˆˆˆˆ€€€ €€ ’€€ €�ã#À0ŽdxÎ0€ ”£ H�”e)H”« pŒåeÈp’”« @‚…e@€Œ“ 0œb¤È0€€€ˆˆˆˆˆˆˆˆˆˆ€"""""""""" The case where a function is merged with a recursive call to itself is handled specially: the head of the recursion is marked with a wider checkered border }™™™™™™™™™™™™™™™˜™™™™™™™™™™™™™™™˜wwwwwwwwwwwwwwwpîîîîîîîîîîîîîîîè��t€€pä€ h”˜ÇœÉqÌ“Î1œ—¤)H¥)J”�)’t¸éH9 A„— 8’pä¡)H!)@Dd)H’h”˜×ˆÇC„cÉ4’�ppàh™™™™™™™™™™™™™™™˜™™™™™™™™™™™™™™™˜wwwwwwwwwwwwwwwpîîîîîîîîîîîîîîîè and the tail of the recursion is inverted uÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿàÿ¿þÿÿÿÿþÿÿýÿßàÿ¿ýÿÿÿÿÿÿýÿÿàŽ?˜þ9Í£ŒÛ?Ìs˜àµ¿mþÖµ­~Úßµ½Û`µ¿mþñ½¯žÚ?½±Û`µ¿mþ÷µ¯îæÿµ­Û`¶?�þùÎ/ç?ͲÛ`ÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿà In the recursive case, you can wind up with a situation like this: �=*ªªª UUUUP*ªªª UUUUP( PP( PP( PP( PP(Œ`8 Q’�$P(–°$ ÐšÐ8P»»»» (’�$ wwww` P’�$PÌÌÌÌÀ0)Ì`8 ÌÌÌÌÀÀPP° ( p`PPÀÀ( ÀÀ`PP° €( p`PPÀÀ( ÀÀ0PP±À À*ªªª s% )cUUUUPÁ-`(Ì*ªªª Á5 (ÐUUUUP±% }¬;»»ºq% EcwwwvØÀDÀÀLÌÌÌÀÀ0LÌḬ̀  8p`pÀÀÀH ÀÀ0H °  8p`pÿÿÀÀÀH ÿÿÀÀ0IŒ Ÿ÷»»»»  :Ršoëwwww`rVoëÌÌÌÌÀÉÚ ÿÿÿù�ëÌÌÌÌÀHR ïÁ:RšoÝqŒŸÝH ÿÿH ÿÿ8ÿÿpH H 8wwwvLÌÌÌLÌÌÌ;»»º In this case, A calls B, and calls C which calls A. All of the time is really spent in B, although only 10% is due to the call from the top-level, and 90% is under a call to C which called A which called B. In this situation, C is also recursive, of course, and also has the recursive border. If you find this display confusing, you should try the MergeNone option and see if you get a clearer picture. MergeDefault means to merge any function that is not in SPY.NOMERGEFNS, initially set to (ERRORSET \EVAL \EVALFORM APPLY EVAL). MergeNone means not to merge at all. MergeAll means to merge any two nodes for the same function. The default for Individual mode is MergeAll. The default for Cumulative mode is MergeDefault. 2 Individual vs. Cumulative Mode 1 Spy initially comes up with the height of the boxes showing the amount of time the function was on the current call stack. This is called ©©cumulative'' mode, since the each function gets the time that both it and the functions it calls account for. There is another kind of display, called ©©Individual,'' in which the boxes are proportional to the amount of time the function was on the top of the stack. For example, if you change the \MOUSE.PROCESS display to Individual, you can get a display like this: …ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþüvÿûÇ¿ÿÿÿûýÿÿß}ûއ xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûªÿãºê¿çm&Û˜®Îï9½»vÿ»vöõû·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþû©ÿûºêÛl–Ûmµ¶ï9½»ž»öü<ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûµûºí_ßm¶Û�µ‡÷U½»îÿ‡vöýÿ~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûº¿ûºî¯ÛM¶›m»¿ûU½»vÿ¿vöõû·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþüz³ûǯç-¶[»ÆûmÃÇŽ ¿w xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ÷{ÿÿýßÿÿÿÿÿÿþÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÀÀÀÀ`ïÅ’g˜À�%nR”$À™™™™™™˜°!~R„ À™™™™™™˜Ð-ÂVRgÀÿÿÿÿÿÿÿÿÿÿÿø™™™™™™˜à�%VRÀÿÿÿÿÿÿÿÿÿÿÿøwwwwwwv�%FR”$Àð`âEŒg˜ÀÀ`!Î3þgýÀœ„X`=Î3Œ÷ØxÀ�!)H�‘! *R„X�!)JR�€À°)H��! *R„X°!)JP�<"""""""ÀÐÎHœ�9 +œ‚›ÿÿÿøÐ9ÎKŒáÀ" ˆˆˆˆˆÀ� H��! ~��!JJ‚�<ÿÿÿÿÿÿþÀ&� H�‘!$F��!)JR�€ÿÿÿÿÿÿþÀF` 0ža=ÄFñ`=)2LñxÀ†Àð`#éK’ÿØÀ�7 JR!$Àÿÿÿÿÿÿÿÿÿÿÿøîîîîîîîæ°?JR!$Àÿÿÿÿÿÿÿÿÿÿÿø™™™™™™˜Ð+ÏK’!$À™™™™™™˜�+ JR!$Àwwwwwwv�# JR!$À `#é3Œ!À@À€ÀÀÿÿÿÿÿÿþÀÿÿÿÿÿÿþÀÀÀ À@Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ€ªªª©UUUU@ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿþUUUVªªªª Àªªª©UUUU@ÏÿÿÿÿÿÿÿÿÿÿUUUVªªªª Ïÿÿÿÿÿÿÿÿÿÿ€@À À€@òLð9Æ3Ìc1€‹¥ÆDd™àH’ä=Æ  Ä� ÊR€%)J“J@‰5)D”¥IZ”!&@€@Å€�ÊP€%)Bƒ À‰=)D”¡I^”!&€ Æ€ŠÊLà9ÉCŒcÿÿÿ@©=)T”™Ày^”9Ç€@Ä€JÊB€!IB"@©-)T”…Kö”!F€ Ä€HÊR‚!)J“B@ù-)}”¥J6”!&@€@Ã(±Œò!&3Ìcy€S¥Æ)cäJ2ç½&  À €@À À€@Ïÿÿÿÿÿÿÿÿÿÿ Ïÿÿÿÿÿÿÿÿÿÿ€@À€ Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ@€@Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ  À€@À À€@À À€@À À€€@À@ À €@ÀUUUUUUUUUU@UUUUUUT Àªªªªªªªªªª€ªªªªªªª€@ÀUUUUUUUUUU@UUUUUUT Àªªªªªªªªªª€ªªªªªªª€@À@P À‚€€  €@ÀE{ñd™æ|Ÿñ@SAŒ“À9’gÝé| À"¤ @›”¥ D‚€¤� BR¤Š¥ R‘ @À,@Ÿ”¡D�@U€ˆBPÅ”%`R‘  À ´ p•”™ÆDâ¿ÿÿÿ¦€ˆBPÆ‹ÿÿÿú™ R‘ Ï@À$ @•”…ä�@T€HBP¤”% R‘  À¤ @‘”¥ $‚€¤€IBR”Š¥ R‘ @Àx‘cæ$ñ@S&yŒ‹À9Œaé À€€  €@À@P€ À€€  €@ÀUUUUUUUUUU@UUUUUUT Àªªªªªªªªªª€ªªªªªªª€@ÀUUUUUUUUUU@UUUUUUT Àªªªªªªªªªª€ªªªªªªª€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À À€@À ÀUUUUUUUU@Àªªªªªªªª ÀUUUUUUUU@Àªªªªªªªª ÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ This display shows that 80% of the total time under \MOUSE.PROCESS was spent inside the function IQUOTIENT. (Whew, something going on wrong there... why isn't it getting the microcoded version of divide?) One thing to watch out for: when you switch between Individual and Cumulative modes, the ©©threshold'' stays the same. (Sometimes the threshold for Individual needs to be higher; otherwise, functions will tend to disappear in the Individual tree.) Also, switching to Individual also changes to ©©MergeAll,'' while switching to ©©Cumulative'' changes you to ©©MergeDefault.'' (SPY.LEGEND) [Function] If you forget what all of the different shadings and borders mean, this function brings up a window that shows what they mean. Internal controls: SPY.FREQUENCY [Variable] How many times per second to sample? Initially set to 10. (Maximum 60). SPY.NOMERGEFNS [Variable] Functions on this list won't get merged under MergeDefault. Includes (ERRORSET \EVAL EVALFORM APPLY EVAL). You may need to add more. SPY.TREE [Variable] This variable (same name as the function) is used to hold the data from the last sampling. You can save it away and restore it using UGLYVARS. SPY.BORDERS [Variable] Used to control the border display on a tree. This is a list of (nodetype description borderwidth texture interiortexture). (SPY.LEGEND) [Function] Brings up a window that shows the interpretation of SPY.BORDERS. SPY.FONT [Variable] Font used to display node labels. Initially (GACHA 10). SPY.MAXLINES [Variable] Maximum height of a node in the graph, measured in multiples of the font height of SPY.FONT. 2 Known Problems With This Version of Spy 1 The 1132 has a bug that will cause incorrectly large amounts of time to be accumulated to the routines that get and send packets to the 3MB Ethernet. It will show up as samples under \3MBGETPACKET (or whatever). The rest of the data in the Spy display is relatively accurate, and you may need to 'delete' that node. Spy doesn't know anything about the interpreter or the internal workings of Interlisp-D. Internal functions that are not REALFRAMEP and don't normally show up on BT backtraces (but do on BT!) will be shown in Spy. This includes things like \INTERPRETER1, which will appear underneath any interpreted function call. Finally, a number of enhancements and extentions are planned; suggestions and requests are welcome.(LIST ((PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC ) STARTINGPAGE# 374) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD LEFT) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO (ARABIC )) (54 12 288 36) NIL) (HEADING NIL (HEADINGTYPE FOOTINGV) (54 27 558 36) NIL) (HEADING NIL (HEADINGTYPE VERSOHEAD) (54 762 558 36) NIL) (TEXT NIL NIL (54 54 504 618) NIL))) (PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC )) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD RIGHT) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO (ARABIC )) (270 12 288 36) NIL) (HEADING NIL (HEADINGTYPE FOOTINGR) (54 27 558 36) NIL) (HEADING NIL (HEADINGTYPE RECTOHEAD) (54 762 558 36) NIL) (TEXT NIL NIL (54 54 504 684) NIL))) (PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC)) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD LEFT) CHARLOOKS (SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF SLOPE REGULAR WEIGHT MEDIUM) FORMATINFO (ARABIC)) (54 12 288 36) NIL) (HEADING NIL (HEADINGTYPE FOOTINGV) (54 27 558 36) NIL) (HEADING NIL (HEADINGTYPE VERSOHEAD) (54 762 558 36) NIL) (TEXT NIL NIL (54 54 504 684) NIL)))))/ÌÌøøT/ø2øT.ÌÌø ø.ÌÌøø.ÌÌøø.ÌÌø ø.øø.øø.ø2ø.ÌÌøø.ÌÆø ø.øø.øø.ø2ø.ÌÌøø.ÌÌøø<ø PAGEHEADING VERSOHEAD<ø PAGEHEADING RECTOHEAD;ø PAGEHEADINGFOOTINGV;ø PAGEHEADINGFOOTINGR+((MODERNMODERN MODERN MODERN HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN/x¤@  H ” HRULE.GETFNMODERN    HRULE.GETFNMODERN    $ BMOBJ.GETFN3MODERN K  $ BMOBJ.GETFN3MODERN ÎPG7X»4 !"    % Á%L BMOBJ.GETFN3<   BMOBJ.GETFN3³  BMOBJ.GETFN3­YÈ 6¤ % 6  HRULE.GETFNMODERN  HRULE.GETFNMODERN’/L BMOBJ.GETFN3‘À BMOBJ.GETFN3ŸL BMOBJ.GETFN3*< BMOBJ.GETFN3CV BMOBJ.GETFN3“€%=^ HRULE.GETFNMODERN    HRULE.GETFNMODERNþ#` BMOBJ.GETFN3MODERN Ei…�A8A8] HRULE.GETFNMODERN )  HRULE.GETFNMODERN<;cÀ•zº