Log of the development of the Smalltalk Virtual Machine ------------------------------------------------------- Mario Wolczko 9-17 May 84 Typed in G/R ST VM, exactly as in the book. 18-30 May 84 Went carefully through G/R VM, debugging. Generated keyword index and instance index. 2 July 84 Wrote the input side of IO.c, incorporating keyboard, puck buttons and coordinates, and milllisecond and absolute time. Also implemented the event queue. Specified the input function in VDM. 3 July 84 First tests of IO.c, using testInput.c. Bugs: 1. X substituted for Y in wraparound for cursor. 2. The event queue was made of type short (not unsigned); unwanted sign extension took place when copying into an int. 3. Reversed sense of subtraction between last event time and current time. 4. Reversed sense of b_down and b_up. (Button changes) 5. Got the buffer conditions wrong; initially thought that I should refine the VDM event queue spec., but felt it was too simple (there's a moral here). Even when all the above were resolved, the code still did not work. The cursor tracks OK, but no sign of life from the buttons or keyboard, and no visible time updates. 4 July 84 Found the problem in IO.c after several hrs.: had failed to parenthesise a defined expr. containing <<, resulting in the precedence being wrong. Had also forgotten to reset the state of a wdbyte() descriptor in testInput, resulting in no display of the time, after the first wdbyte(). Had the test program remove only one entry from the queue for each event; this exercised the full buffer conditions by generating events faster than they were consumed until excess events were discarded. This could be done by constantly moving the puck. Also tried various refresh rates for the cursor: up to 50ms between refreshes seems to be acceptable. 5 July 84 Coded version of BitBlt using the PNX wrasop() call. Fairly simple transformation, except for the fact that: a) wrasop() does not cater for halftoning. b) Not all 16 BitBlt combinations are provided: solved this by doing one or two wrasop()s (The optional first one inverting the dest.) 6 July 84 Entered a test program for BitBlt, which didn't work at all. However this did not matter, as I discovered that wrasop() requires its bitmaps to be aligned on double word boundaries, and be multiples of 64 bits wide. Since this is far too restrictive for the ST BitBlt, decided to abandon the use of wrasop(). Also found that my interpretation of halftoning was at variance with that in G/R(p.360 "seaming"). Accordingly began coding the ST BitBlt (as in Ch.18 of G/R) in C. Fairly straightforward simple translation took less than an hour. 7 July 84 Refined the C BitBlt for speed (taking code out of loops, common sub-expressions, macro substitution). 8 July 84 Further minor refinements to BitBlt. Occurred to me that I didn't know for sure that the Perq stored its screen image with LSB to the left, as ST requires. Also still don't know how I'm going to refresh the screen (i.e what to do with the beDisplay primitive). 9 July 84 Examination of Perq documentation showed that it stores the frame buffer with the MSB in a word to the left - which I beleive is the opposite of what ST requires! Also scanned the documentation for some idea of where the screen might be in memory. The Pascal documentation for RasterOP talks about the screen as a location "SScreenP", imported from module Screen. Wrote a short Pascal program to print out the value of this constant - came to 256K exactly. Tried writing to this address in C but just got a memory fault; does this mean that the screen is in a different address space? The only method I can think of which will get over these two obstacles is to maintain a Perq format screen image, which is built by copying the ST screen Form (fixing store alignment and bit orientation problems in the process), and then wrasop()ing this image to the WMS window (which the WMS then uses to refresh the real screen image). The prospect of doing this every 100 ms (if it can be done at that rate) is appalling. If I could write directly to the screen, I could systematically go through the virtual image and fix the bit orientation of all Bitmaps. (and subclasses thereof - e.g. character fonts) It is fairly straightforward to alter bitblt() to work in the opposite sense (i.e. MSB to the left). However, can I be sure that the methods in the virtual image don't somewhere depend on the bit orientation? (i.e. are Bitmaps only manipulated via bitblt?) All this is purely speculative without being able to write directly to screen memory anyway. 10 July 84 Empirical tests of bitblt have determined that the bits in a word are the correct way to match Perq and ST - thank heavens for small mercies! Started debugging bitblt. Bugs found: 1. Value of 'word' incremented in test in for loop, but used within loop - simply had to increment at loop end. 2. Error in calc. of srcDelta: the ST operator precedences in the original are very confusing (well, they confused me anyway). Still haven't got over the screen addressing problems though. Messed about with window descriptors. 11 July 84 Got bitblt working to my satisfaction (using testbitblt). 12 July 84 Further investigation under POS revealed that I can write directly to the POS screen, using a pointer set to 256K. This is frustrating!! Tried some more to write to the PNX screen (using various char, short and int ptrs.) but with no success. Started on the object memory interface - spotted that Perq and ST store bytes within words differently - not much of a problem. Coded most of the object memory quite easily - C macros are very convenient for this sort of thing. 13 July 84 Typed in code for all of Object Memory. 14 July 84 Coded some of the process switching module. (checkProcessSwitch-addLastLink). 15 July 84 Coded the dispatch table and all of the Stack and Jump Bytecode routines. 16 July 84 Tidied up various of the macros entered in the last few days (parenthesised args, removed possible side effects, etc.) Tried out the C preprocessor just to make sure it could handle deeply nested long macros. Everything OK - had to change the names of various local variables and field selectors so that they didn't clash with macro names. 17 July 84 Coded Jump and Send Bytecodes, adding macros to various modules. Heard of release of Berkeley Smalltalk - who needs it???!!! 18 July 84 Tidied up and checked all of recent coding; moved some macros and code around to reflect order of definition in G/R. 19 July 84 Found a few errors in Bytecode dispatch and Context Macros during first attempts to compile: 1. Missed a right parenthesis in isBlockCtx macro. 2. Have to bracket statements within the true part of an else if I have a macro there (otherwise get premature statement termination). Compiled Process, OM and BC successfully (even if they are incomplete). Completed BC (on paper). 20 July 84 BC compiles OK. Benchmarked some of the Perq C basic functions. Results Assignment x=; 0.7 us Addition x+x 4.4 us Empty fn. call, no args. 22.0 us Empty fn. call, 1 arg. 26.5 us The x is a register variable. Invoking the code improver had no effect, except on addition, which reduced to 3.7us. Made some changes to the OM macros to avoid scope problems (local variable with same name as next outermost in scope, both variables reqd.) 21 July 84 Coded Float Primitives, began Array Primitives. Decided to do away with the "success" variable for primitives. 22 July 84 Completed coding array and storage management primitives. 23 July 84 Discovered that modf() doesn't do what I expected; modf(-1.5,)==-0.5, not 0.5. 24 July 84 Benchmarked setjmp(), and floating point addition and multiplication (to see how expensive it is to trap prim. failure in Flt.Pt. prims). Results: setjmp() 51us / call fl.pt. add and assign 120us / call fl.pt. mult and assign 225us / call Concluded that setjmp() isn't overly expensive! Modified floating prims to trap flt.pt. errors. Coded Control and System prims, started on IO prims. 25 July 84 Finished IO prims to the best possible at the moment (don't know a few details, still haven't found a good way to do the screen). 26 July 84 Tidied up all of the Perq and C portability tests. Began module testing - redid Input and BitBlt tests, adding a new BitBlt test which change the cursor and bitblt'ed areas of the screen under user control. Small problem when I didn't realise that the clip args. to BitBlt MUST be within the dest. form. 27 July 84 Benchmarked a whole screen wrasop: 50ms per refresh. This means if we accept a 50% drop in performance we can refresh every 100ms. Yuk! 28 July 84 Started work on debug format for snapshots. 29 July 84 Coded debug format snapshot save and load. 30 July 84 Started compiling modules. Errors in ArrStorePrim.c: 1. Missing right parentheses. 2. Macro in OMMacros.h without a #define. 3. Incorrect declaration of bit fields. 4. Missing left brace in then part of if statement. 5. Misspelled id in a macro. 6. Extra left parentheses. Errors in BC.c: 1. Use of argCount as macro name and variable name. 2. Extra right brace in Exec.h Errors in ControlPrims.c 1. Exec.h not inlcuded 2. Primitive dispatch table not defined. Error in FloatPrim.c 1. Mistyped id. Errors in IntegerPrims.c 1. Extra right brace. Errors in PrimTable.c 1. Misspelled external ids. Errors in Process.c 1. Misspelled macro name. 2. Missing right parenthesis. 3. Extra right parenthesis. Errors in SystemPrims.c 1. Missing arg. to macro. 2. Undeclared external id. Added code to print bytecode and message traces. 31 July 84 Wrote makefile and began real compilation. Errors: BC.c: use of #ifdef within a #define. Snapshot.c: Wrong filenames, forgot to call fetchCtxRegs. Got snapshot working, but still no bytecodes executed. Creating an image from scratch is difficult!!! 1 Aug 84 After a few minor changes to my image, executed two bytecodes at 10:05. The bytecodes were: push receiver, send literal 0, 0 args (which invoked the quit primitive.) Noticed a bug: an object had its ref.count decreased from 255 to 254; source is a mis-declared MAXCOUNT in OMMacros.h. Executed a primitive snapshot at 1:48. (after much faffing about because of two extraneous lines in an object in the image). Wrote some code to do a factorial, but couldn't get it working. 2 Aug 84 After finding several faults in the image, successfully began execution of the factorial method. Failed at an extended conditional jump, because of an incorrect offset calculation (easy to find with the help of a trace and a snapshot). Second bug: incorrect branch taken. Two problems: 1. Incorrect extraction of offset from extended conditional jumps. 2. The entries for extended conditional jumps were wrong in the dispatch table. Later problem: not evaluating problem; incorrect extraction of temporary count from a method header (missed two trailing zeroes in a hex constant). At 4:15, successfully executed 5 factorial!!!! We're on our way!!!! 6 Aug 84 Began an attempt at benchmarking the machine by evaluating 5! 1000 times. Several unsuccessful attempts (mainly due to image faults). Found a bug in the VM - not zeroing the ref.count when deallocating (this is important because it's not zeroed or initialised elsewhere.) Also found a premature return within allocate(), which resulted in the fields of a new object not being nilled out, and therefore incorrectly reference counted. Finally executed benchmark, taking 29.4s for 74009 bcs. Works out at 2500 bc/s - v.promising. 7 Aug 84 Added the ST! comments to the C source, so that the ST source can be merged into it. Re-compiled with the object code improver enabled; absolutely no difference in code size!! 5 Nov 84 Tidied code in Process switching to ensure that Processes don't disappear when lists are being manipulated. Also speeded up BitBlt by incorporating the transformation suggested by Pike in the Blit papers. Now does about 210 cps equivalent. 14 Dec 84 Virtual Image arrived from Xerox. Copied from tape onto VAx, and then via 600bps serial line to PERQ. Ran out of space on PERQ during copy, but only had to retransmit last 70k or so. Image verified consistent with VAX copy using sum(1). 15 Dec 84 Made backup on image on another PERQ. Printed all sources on the distribution tape. Started last stages of version 1 of VM: mods for display, and to load/save standard snapshots. 17 Dec 84 Finished above changes, compiled, and did first test runs. After initial byte-sex and offset problems, image loaded correctly (it seemed) but first bytecode would not execute. Discovered 2 errors: 1. Not initialising free chunk list head for largest chunks. 2. When reading object table entries not assigned bit fields (odd, pointer and free) correctly - stupid mistake in C! After finding and fixing these, executed 61 bytecodes correctly (or rather, the right 62 bytecodes), then went astray, resulting in a recursive does not understand error. 18 Dec 84 Discovered error in definition of indices into class Point which resulted in primitive MakePoint not setting the x instance variable correctly. Corrected this, but not much more progress. This was due to another bug involving Points: when making a point, the fields were inadvertently converted from oops to words. The next run went for 99 bytecodes. 19 Dec 84 Found that the 100th bytecode coincided with the the first input: decided to postpone input until the traces had executed correctly. The next run went for 144 bytecodes before a message was sent to true that should have gone to the DisplayScreen. Discovered that I had used a macro as an argument to another macro (fetchClass) that had side-effects, leading to an off-by-one stack error. The next run executed a further 10 bytecodes, before primitiveBeDisplay failed due to incorrect bitmap step size. A further run failed because the order of fields within a Form as indicated in the blue book is different from that in the image. The next run exhausted distributed trace2, and went until bytecode 720: made the mistake of only allocating one large free chunk, (supposedly larger than 64K!). Once this had been fixed the the machine continued correctly until bytecode 981, when a primitiveInstVarAt failed due to the wrong check being applied. After fixing this, the program ran for over 2000 bytecodes, but a discrepancy arose near the end when trace3 said that 16383@16383 invoked primitiveMakePoint, whereas a fast send to primive 11 in fact occurred. I assume that this is OK. Later the program crashed (after exhausting trace3. Decided to copy the source to the VAX for further tests. 20 Dec 84 Noticed that crash had occurred at bc 2000 - correctly assumed that the input was responsible, and fixed the bug. Saw the machine run over 9000 bytecodes with full trace on. On the VAX side, had to make the expected changes to the IO module, and in addition had to alter the order of fields within the instance specification struct: the VAX it turns out uses the opposite order to that of the Perq. Also, had to explicitly mask input bytes, because the VAX sign extends char- to-int conversions. Once this was done, the VAX version ran (with limited/no trace) for 440000 bcs, before crashing when the compacter was invoked. Found one bug (stepping through oops in ones instead of twos) which enabled it to survive one compaction, but it still crashed on the second; cause unknown. Christmas Vac 84/5 Found a few bugs by inspecting code: 1. Although I wasn't using the `space efficient' garbage collector, I failed to notice that all large objects in the distributed image have the extra word. This caused the compacter to fail. Also added code to signal low free space - the ST source indicated that prSAtOopsLeft was an essential primitive. 2. Noticed that when the compacter had done its job and collected together a large free area, I was allocating it to one chunk, even though it could be bigger than 64K! 3. I wasn't setting the free bit of pointers not present in the image o.t. and therefore was 10000 ptrs too short!! Coded the mark/sweep collector. 2 Jan 85 Corrected above bugs and tried again: much the same activity, but machine crashes much later (2.5mbytceodes) due to a recursive not understood error. Monitored the activations of primitives, and went away and inspected code. Found some errors (but not the cause of the fault): 1. Faulty stack handling in prNewMethod. 2. Incorrect test in prPerWithArgs (< instead of >). 3. All float prims return TRUE (i.e. failed) when they have succeeded, and vice versa(!) 4. Noted in the ST src that prInpWord should fail if the event queue is empty: I wasn't even testing for an empty queue. 3 Jan 85 Added trap code to detect `message not understood' errors and found that the first occurred just after the bitblt of the letter y, at bytecode 6038. Located error in prCopyBits: popping one too many items off the stack. After that, seemed to perform all of screen display (100000 bytecodes) (difficult to tell on the VAX), then crashed again (recursive n.u.error). Located several more bugs by inspection, and by looking at the prim activation trace: 1. prSAtOopsLeft was failing: the no. of words left may be a 32-bit integer, and I was restricting it to 16 bits. Also wasn't allowing nil as a semaphore. Noticed that the first process switch was taking place at bc 101400, and from that point on the wrong code was being executed. Looking at Process.c revealed: 1. I was emptying the sema queue incorrectly (post- instead of pre-decrement used). 2. Process switch must be checked for after a wait or suspend - I was only checking every n (=50) bytecodes. 3. Incorrect ref.counting when moving a process on/off a queue. Put some effort into understanding the scheduling mechanism, and think I corrected this OK (have to ensure that a process doesn't inadvertently dispappear when switching). 4 Jan 85 Corrected above errors, and machine seemed to run OK: refreshed screen and entered poll loop. Executed 1.5 million bytecodes before I got bored. Moved code across to Perq and re-compiled, but couldn't get a fast (5bps!) consistent run. Occsionally it ran at 1/10 bps, and I killed it off. The rest of the time it went in fits and starts (avg of 5bps) but crashed giving a core dump. Crashes were not consistent, therefore I assume not of my doing. Tried using the lock() system call, and nicing by --10, but it didn't seem to make much difference. Tried to see if combinations of unions and structs could be used to force an object memory array to be aligned correctly: nothing worked. However, allocation seems predictable, so it might be worthwhile just adding a declaration where necessary so that proper alignment occurs. Anyway, an aligned version (i.e.om[] in place of *om) on the VAX ran slower - maybe there's a moral here! Recompiled the VAX version with the code improver invoked: crashed again as expected!! 7 Jan 85 Tried getting the VM to run faster on the PERQ: not using the window manager had the most effect, but it just won't run consistently or long enough to display anything. Altered the allocation and splitting of free chunks so that thay tended to stay at the same end as the objects in the image. 8 Jan 85 The allocation change made no difference to PERQ version's speed. Found a mistake in the compacter (by accident; the compacter wasn't being invoked) and three mistakes in prNewMethod: 1. My earlier corrections to the stack handling were incorrect. 2. I wasn't writing to the header field with NIL. 3. I wasn't writing to the header field with a header (the book doesn't do this either - I suspect it's another book bug). After correcting these (and adding more facilities to the front panel) everything ran OK again on the VAX. Added a screen dump facility, saved the screen after 100000 bytecodes, and transmitted it to the PERQ (via serial line) where a program redisplayed it. All the chars seemed OK, but there were no half-toned areas, and the windows had no borders. 9 Jan 85 Fixed the BitBlt problem: it wasn't halftoning properly if there was no source form and the source width and height were zero. Also added some checking code to the primitive as per the Smalltalk source. Successfully displayed a screen on the PERQ! 10 Jan 85 Placed all source code under RCS. Started work on changing the VM and writing code for the PERQ so that the VM could run on the VAX and display and input from the PERQ. Mostly reused old code from the I/O and BitBlt module. Decided on the following arrangement: The VAX transmits to the PERQ changes in the display in one of two ways: a) If no source form is used in a BitBlt, the halftone form is transmitted with clipping boundaries and a combination rule. b) otherwise, only the area of the display bit map that has been operated on is transmitted. Both of these are trapped in the prCopyBits primitive. The PERQ transmits to the VAX info about mouse location, button and key changes. Everything seems OK at first, except that is seems impossible to get the PERQ to read the RS232 line fast enough and display the results. I've used two processes at the PERQ: one for VAX->PERQ info, and one for PERQ->VAX. The VAX->PERQ processes reads the line and performs BitBlts as appropriate. It just can't cope above 1200 baud. 11 Jan 85 Split the input process into two: one which read data from teh serial line and sends it down a pipe, the other which reads the pipe and performs BitBlts. Seems a lot better (I've also altered the niceties to help). Saw it fill the screen, give me an error message (`Bad event type'), and refresh the browser. 14 Jan 85 Discovered that the bad event message was due to the input loop reading an absolute time event (type=5) and performing a right shift. Since it is encoded as a SmallInteger (m.s. 3 bits for type, 12 bits spare, 1 SmallInteger tag bit) this means that it is negative, and when shifted right the sign bit is extended. The book gives no indication that I should use a large integer, but I can't think of anything better. Changed the VM to return large integers if necessary. Everything sprang into life!! Succesfully browsed, and executed 3+4!!!! Only problems were due to the transmission line or the PERQ failing to read it. Executed millions of bytecodes!!! 15 Jan 85 Tried altering the code to avoid bufferring problems, so that I could play for a few minutes at a time. Unfortunately, couldn't get the PERQ to keep up with the serial line. Managed to try 2 sqrt: returned a `divide by zero' error: suspect that floating point doesn't work. 16 Jan 85 Careful tracing showed that the f.p. prims were failing due to what should have been obvious: the VAX doesn't use IEEE format. Corrected this, and the screen correctly displayed the selected options (instance/class) in the system browser; this had not happened before. However, found it impossible to improve the quality or speed of the comms. line. 21 Feb 85 Copied all source and the image over to the Apollo. Converted the source into binary (from hex) with no problems. Changed all the machine-dependent #defines and #ifdefs to work with the Apollo. 22 Feb 85 Compiled the source first time on the Apollo, but it won't run: gets the wrong first bytecode. Fixed by reversing the byte access within HCbyte(). Runs ok until at bytecode 741 it starts getting zero bytecodes. Cause unknown. Crashes shortly after with a memory fault 25 Feb 85 Found that it wasn't finding the right method at bc 741 because class Form was being completely overwritten at b.c. 720. This was due to an arithmetic error when allocating the display bitmap. Apollo C doesn't sign extend the difference of two unsigned shorts, and was therefore using the first free chunk on the large free chunk list when in fact it was far too small! When this was corrected the machine ran for 110000 bytecodes with identical output to the VAX V.M. 26 Feb 85 Tried getting the Apollo to display bits on the screen - absolutely fruitless. 27 Feb 85 Display works: moved all graphics call into Pascal. Also found a subtle bug: access 257 elements of the 256-element activation array!! The big question is, why did it ever work on the VAX?? 28 Feb/1 Mar 85 Tried getting some input from the Apollo, without success. The manuals are just terrible!! 4 Mar 85 Input finally works!! Have successfully executed 3+4, 2 sqrt, browsed. Fails when I try to scroll. Found the scrolling problem: attempting to refresh an area of the display with negative height. 5 Mar 85 Played with the system. Started executing the benchmarks, but didn't have the patience to wait!! Succesfully browsed, executed methods (loop from 1-19 of factorials), process forked, and lots of other things. Text editing is the only anomaly..after selecting text, a keystroke does not delete the selection. However, the internal representation seems consistent. 6 Mar 85 Played some more. Text editing works in the System Transcript, but not in the System Workspace!! Also, the actual and computed positions of the cursor sometimes differ: cause unknown. Various messages in the System Workspace print to the Transcript ok (e.g., Smalltalk oopsLeft) but do not print anything if "print it" is selected in the Workspace. The accounting of free words does not work. Compaction seems not to work. Have altered the VM so that it uses the whole Apollo display, but can't get ST to use all of it (because of the compaction problem, perhaps). Commited all source code back to RCS. 10 Mar 85 Fixed cursor/mouse problem: have to update the mouse position when the cursor is moved!! Increased the object memory size to 1000Kb, and can now use the whole display. Compacter still fails though. 12 Mar 85 Increased the object memory (on the Apollo) to 2000Kb. Encountered a bug: isIntVal was coearcing its argument (which could be a 32 bit quantity) to be a 16 bit quantity...this led to a failure in prCoreLeft. 15 Mar 85 Installed the VM on the newly arrived PERQ2: worked first time, but was overwhelmed with input do to the erratic cursor motion generating spurious events. 18 Mar 85 Played some with the PERQ version: funnily enough, editing works in the System Workspace, and word accouting seems to be correct. The compacter still fails though. Currently running with 1000Kb object memory. 26 Mar 85 Typed in code for mark/sweep collector and snapshot save. No success in debugging (mainly due to unpredictablitty of PERQ). 27 Mar 85 Found error: assumed that the used the `extra' word of the book, whereas in reality it doesn't. This was causing the compacter to fail. (See entry for Xmas vac, 84/5). 28/9 Mar 85 Still no success...there's definitelt a fault in the mark/sweep collector, as the system won't run properly after it: doesn't accept any input, but refreshed the screen ok. Another strange phenomenon is that there appear to be six garbage objects in the distributed image: they're all contexts, associated with the method snapshot:thenQuit: in SystemDictionary. 2 April 85 PERQ2 has broken...have transferred code to VAX. Found a couple of errors in the code for save_snapshot...not dealing with free chunks properly, and not writing out the size of the object table properly. Once these were corrected, the VAX version writes and re-reads a snapshot correctly. 11 April 85 Out of desperation returned to the Apollo. Spent a while finding that a bug I had corrected on 25 Feb had re-emerged: probably the bug fix was lost in all the to-ing and fro-ing between VAX and Apollo. After (re-)correcting the bug, everything ran OK. Wrote a snapshot, which was read back OK, except that it wouldn't take any input! (This behaviour had occurred on the PERQ2 earlier). Cause unknown. 12 April 85 Found and fixed a bug in prSnapshot...having written the snapshot the VM is supposed to replace the top of stack (which is the dictionary, Smalltalk) with NIL. 15 April 85 PERQ2 was fixed...moved back there. 16 April 85 Can't run garbage collecter on PERQ - fails every time, crashing the machine or entering the microcode debugger. No ideas. 17 April 85 Started on the Apollo again. Added a single step to the Apollo code, in an attempt to determine why it was failing. 21 April 85 Added the symbolic stack dump facility. 22 April 85 The new snapshot is not working because a context is deallocated prematurely: i.e. the refce count falls to 0 even though something is obviously pointing to it. Other problems: all objects re-loaded seem to be word objects; the VM crashes after writing a snapshot. 23 April 85 Fixed the snapshot: two bugs were corrected (a) The garbage collector should have increased the refce. count of the active context (not the active process, as G&R state) (b) The Apollo seems to have a bug in the C compiler: simplification caused the correct pointer/word bit to be written to the snapshot. Successfully snapshotted and continued, then loaded and executed the snapshot. Checked back in to the VAX again. 5 May 85 Started thinking about the file system interface. 10 May 85 Transferred (at 4th attempt) Smalltalk.sources to Apollo. 15 June 85 Changed to PNX 4.0. Unfortunately, st no longer works. No consistent crashes were obtained though. It's all a mystery. 19 June 85 Initial thoughts were that the PERQ might be up to its old tricks again (i.e. paging, due to a larger kernel). Investigation doesn't seem to bear this out though. Reduced the object memory by 100Kwords, and did direct output to the screen (thereby saving another 100Kb), and it didn't make any difference. I'm absolutely puzzled. Maybe the earlier problem (causing a crash in the mark sweep collector) has become more severe. 20 June 85 Started integrating the new mouse into the Apollo code...no serious problems anticipated. 21 June 85 The mouse code is present, but there are two outstanding problems: 1) Whenever a key is struck the cursor leaps up to the top left of the screen. 2) Occasionally, a button release event seems to get lost. 24 June 85 Investigated further. The middle button seems capable of generating a spurious key-down/up, when in reality nothing has happened. It looks like unreliable hardware/software. Still no clues as to the jumping cursor though. Also experimented on the PERQ: split the object table into three arrays: one for the location (32 bits), one for the count (8 bits) and one for the remaining three flags (all in one byte). It worked!! Successfully ran and snapshotted, but wouldn't reread the new snapshot. 25 June 85 Removed all remaining usage of bit fields, doing everything by ORs and ANDs. After introducing a couple of bugs (setting a bit with an OR, no less) everything worked. Snapshotted and reloaded twice. Finally the PERQ implementation is off the ground. 26 June 85 Inaugural meeting of OOPS. 27 June 85 Checked into RCS. 2 July 85 Altered reference counting to use Deutsch's cyclic trick, i.e. the l.s.b. is the overflow bit. Also removed all redundant reference counts when constants such as nil, true, etc are stored or pushed. Recompiled, but failed after 80 bytecodes. 3 July 85 Failure due to incorrect setting of ref.count when reading a snapshot; failed to do a left shift. Also ref.counted the wrong way in retVal(). Fixed these bugs and it ran OK. Coded (simply) CharacterScannner primtive (103). Early tests looked promising, but strange things happen (such as bits of text are missing). 4 July 85 Altered prScanChars() to use its own fast BitBlt, and cache local values. Several problems had to be ironed out before it worked: 1) Caching of instance variables was not done correctly. 2) Off by one errors in the indexing code 3) Could not assume that some instance variables were SmallIntegers (this merely caused the prim. to fail unnecessarily). Returned to the snapshot problem: after much investigation noticed that TRUE was being deallocated after 2000 bc. After much more head-scratching realised that my non-ref.counting operations assumed that TRUE and FALSE had saturated counts, when in fact they didn't. Altered the mark/sweep code to saturate them. 15 July 85 Monitored the instances of BitBlt which were being invoked: discovered that they largely had no source (only halftone) in combination 3 (copy). Optimised BitBlt for this case. 23 July 85 Noticed strange problem: VM loops infinitely if I try writing a snapshot after doing some work (like creating a view); is OK if I don't. I regard this as a probable PERQ funny, and hope that it goes away of its own accord! Changed the location field of the object table to directly point (via WORD *) to object memory. Had to alter the compacter extensively, and one or two other places slightly. This should save on a few indirections, and speed things up slightly. The intention is to eventually use PERQ RasterOp, using the loctn field as a bitmap ptr. (This will require an image change of course: 1) All bitmaps will have to 64bit multiples (width) 2) " " " " " be allocated using rectangle(3) 3) Size and class fields will be moved into dedicated arrays 4) As a side benefit, direct RasterOps to screen will be possible by placing a 0 in the loctn field of the display bitmap. Recompiled, but the VM never got past 42bc, giving a "message not understood" error. After much head-scratching, checked back into the VAX, where everything worked of course. 24 July 85 Took the new code to the Apollo, where it also worked. The change speeded things up by about 10%. This suggests that the problem is something very peculiar to the PERQ (such as the infamous char *). 31 July 85 Hmm..discovered that the free list is messed up immediately after the snapshot is loaded. However, I can't see anything that would cause this! 1 Aug 85 Seems like yet another PERQ bug: the use of an intermediate variable in the code for allocating the free list seemed to fix the problem. The snapshot problem still remains, and a new funny has appeared: if a create a workspace and type "Time millisecondsToRun: [100 factorial]", the VM crashes between the [ and the 1, giving a "recusive not understood" error. This definitely seems like a PERQ funny. 7-8 Aug 85 In an attempt to tidy up the C code, made the O.T. loctn. field into an array of unions; this should stop the C compiler complaining and eliminate the previously discovered PERQ funny (which reqd. the intermediate variable). 26 Aug 85 Added direct, cached pointers to the active and home contexts. Access to fields of these contexts now goes via direct pointers and structure casts. Seemed to integrate reasonably smoothly, except for a couple of bugs when I omitted to load the cached pointers. 5-10 Sep 85 Played with BS II on a SUN 2/50. 13 Aug 85 Checked code (after addition of pointer caches) into VAX, and moved to Apollo. Wouldn't work initially---found that I had missed a "." in makefile which meant that one of the modules wasn't recompiled! 18 Aug 85 Added script facility. Didn't work---realised that other things such as prMousePt also do input. Altered the script to also keep track of Mouse[XY] (trivial, really) then it worked OK. Would be nice if the cursor moved too; I'll save that for a rainy day! The only problem that might occur is that the time primitives will return the real answers rather than the simulated time, but I don't think this should cause much of a problem. 28 Oct 85 Tried out a relative mode tablet on the PERQ...seems to be the just the thing I need! 29 Aug 85 Started investigating bugs: error in positioning of text cursor is definitely due to a bug in prScanChars, random crashes are definitely not. 12 Nov 85 Fixed bug in prScanChars; was incorrectly restoring value of destX when exiting the loop under condition CrossedX. 13 Nov 85 Ran a largish script (1.7Mbc) on the PERQ, and re-ran on the VAX for profiling purposes. Profile showed that >30% of time was spent in object (de-)allocation, >15% in message send/return. Unfortunately, the VAX did not do the same thing as the PERQ (reason unknown). Worked on fixing the PERQ tablet input to get coordinate system shifts right (as VM moves cursor/tablet). 14 Nov 85 Finally fixed the tablet problems. One reason that the VAX wouldn't run input scripts identically to the PERQ is that they are binary files, and the two machines read the byte-order differently. Another is that input was not enabled for the VAX! However, when a suitable script was tried (one that caused a crash), the script file was exhausted too soon; a snapshot was written, but no further input remained. The assumption is that either a snapshot causes premature termination of script-writing, or that the script file buffer is not being flushed. 15 Nov 85 Tried a different script file; seemed to work OK. Caused the VAX to core dump due to stack overflow (infinite recursion on c_down_inner). It seems that a class was trying to be de-allocated. The problem only seems to occur after a snapshot...suggests that the fault is in either: a) the compactor b) the garbage collector, or c) the snapshot code. [Aside: had to build a new, bigger version of dbx, to cope with the large number of procs/funcs.] Ideas: create a script that causes a crash (due to recursive-not-understood). This might require a further script to create the appropriate image in the first place. 16 Nov 85 Tried out ideas: NB: LowWaterMark at compaction was different on PERQ and VAX; cause unknown. After protracted in-fighting with dbx, discovered that the recursive not understood error was correct, and the class hierarchy at that point (from StringHolderController) was intact. The instruction pointer seemed way off the end of the compiled method; don't know how it got that way. 18 Nov 85 Noticed that at the point of failure the message to be sent was = on identical Symbols (#normalCharacter:). However, the class pointer of the symbol had 0xFFFF in it!!! Also, this ptr was OK after initial loading of the image....interesting! Finally discovered the problem: the ref counting code used a WORD rather than a BYTE when counting up, do didn't detect the transition to stickiness and correctly set the sticky bit. In fact when the r.c. got to 256 it deallocated the object! Fixed this fault, then ran a substantial test OK. Checked in at VAX. 19 Nov 85 Added PERQRAW mode to keyboard decodeing--can now ^C in safety! Checked in at VAX *** Code frozen at version 2.0 *** 20 Nov 85 Improved the method lookup cache code by optimising array accesses and expanding the size from 256 to 1024 entries. Inspected the corresponding assembler code before and after; still a great deal of room for improvement. Logged a script of a short session during which I created a project, opened a class browser (on Time), edited and compiled a method (currentTime:) and executed Time dateAndTimeNow. Reran this on the VAX and saved the profile. 21 Nov 85 Wrote a program to convert a standard Xerox image into a new format, with the size and class fields separated from the object body. 22 Nov 85 Modified the program above (x2m) to saturate the ref. counts of true, false, and nil, and make 0 an unusable oop. 23 Nov 85 Modified the script mechanism to use absolute bytecode counts rather than deltas; the use of deltas assumes that an event will occur within 64K bytecodes, which is not necessarily true. Added detection of the deselect event to the PERQ version. Moved the size and class fields of objects into separate arrays; had to modify the compactor and garbage collector, and other stuff too. Also had to update the snapshot module to use the new format. 25 Nov 85 Tried sorting out bugs in compacter...got a few, at least one remains. 26 Nov 85 Fixed compacter and a couple of trivial mistakes in the snapshot routine. 27 Nov 85 Wrote a PERQ BitBlt using wrasop(). 28 Nov 85 Modified lots of stuff to allocate, deallocate, save and load bitmap objects. 29 Nov 85 Almost got BitBlt working. 30 Nov 85 Realised that I had goofed on BitBlt (in terms of how the halftone form is used) so had to alter it drastically. 2 Dec 85 More work on BitBlt...finally believe it to be working. Some of the problems were: 1. The PERQ doesn't like being given a non-existent area of source form, even if the result of using this source form will be clipped sensibly. 2. Silly programming errors. The VM now redisplays properly, but crashes after a while. 3 Dec 85 Found bugs in prBeDisplay and prCursor concerned with bitmaps, and also fixed a bug in saveSnapshot. Noticed that CharacterScanner was failing an awful lot, due to destY being nil. Assumed that this only occurred when not displaying, and improved the code accordingly. Made a few other cosmetic improvements: added a macro to add an oop to the free list; mader the cursor go to 0,0 at startup; made loading of the object table faster; trapped SIGHUP. 4 Dec 85 Fixed a couple of bugs in the snapshot code: the object table was not being loaded properly, and neither were bitmaps. Seems to run OK at times, but fails at others due to a huge amount of space being reclaimed by the garbage collector. Checked in to the VAX. 5 Dec 85 Wrote my first microcode: doubles a 16-bit integer!!! Also tested the speed of the umcall() entry: called 10000 times in 3-4 seconds, which gives at worst .25ms per call: not bad. 6 Dec 85 Tried calling microcode using umenter: much faster than umcall (factor of 3-5?). Had to write some assembler to do this: discovered that the assembler does not coincide with the microcode manual a great deal! Modified x2m to swap bytes within byte objects and compiled methods: worked first time! 7 Dec 85 Moved the position of SmallInteger tag bit in object pointers from least sig. to most significant. Required surprisingly few changes. This was probably due to the fact that I forgot to do about half of them! 9 Dec 85 Made remaining changes for tag bit move. It all seems to work again, and seems noticeably faster. Ran a couple of the standard benchmarks: seems to go at about 1.5kbps. Tested speed of doInput() in anticipation of the move to microcode: 625 calls per second, which suggests we can tolerate 30 calls a second without undue degradation. However, it may be worthwhile optimising (by use of assembler, or open-coding, or avoiding wgread()). 10 Dec 85 Examined cpp ouput for BC.c: decided that Deutsch-Bobrow and context caches are the way to go. Created the addrOfOop() macro in anticipation of caching lots more state. Added direct pointer caching for instruction pointer and stack pointer, and for receiver and method. 12 Dec 85 Got the direct caching to work. Had one minor problem when forgot to restore ip, sp after a compaction. Started on the Deutsch-Bobrow garbage collector. Made extensive changes to the stack manipulation macros, and added the endTransaction() call. The call is to be invoked whenever there is a change of context. Also added some uses of the receiver pointer which I had overlooked. The output from the C preprocessor looks as if it should be quite fast now. 13 Dec 85 Continued work on D-B. Decided to implement a slower, but simpler endTransaction(), without macros. It's quite a tricky algorithm, really. Also made a change to counted() in OMMacros: all oops below and including mustBeBoolean: are assumed to be saturated. 14 Dec 85 Added the context counter described by Ballard & Shirron (Bits of History, p. 146), to detect when a context could be disposed of upon return. Required changes to BC, ControlPrims, and Process. Also altered prNew to add new objects to the ZCT. Then decided that the context counter was superfluous. This algorithm has me confused! 17 Dec 85 Continued with D-B: all sorts of complications have arisen due to the fact tha a transaction ends when the context changes. Maybe it's worth going straight to a context cache. 18 Dec 85 Discovered a bug in prFracPart---don't think that primitive has been tested at all before---wasn't returning a value! 20 Dec 85 Added a new macro for objects created and placed on the stack -- pushNew(). Removed a few redundant macros--NRpush, NRsac, NR2sac. Fixed the low space notification to only notify when the limit boundary was crossed (and not per allocation when space is short). Changed hasObject() to scan the scan. Wrote a faster version of transfer(). Changed lastPointer() so that oops above the top-of-stack in contexts were not included ---**** a genuine original speed-up!-**** 21 Dec 85 Fixed some r.c. bugs in prValue() and prValWithArgs(). The VM now runs for 100-200Kbc, then crashes, presumably due to a ref. count being out. Altered transfer() to become transferAndPop(), and faster. Added keepActiveContext and startNewCtx macros. 30 Dec 85-1 Jan 86 Speeded up a lot of the stack access, especially within primitives, due to no more ref.counting of the active context. Found a ref.cnt. bug in prValue(), prValWithArgs(). Finished VDM specs of 3 garbage collection schemes: mark/sweep, ref.counting, and Deutsch-Bobrow. Wrote pseudo-code for a pool of contexts, and for multiple non-ref-counted objects. Also thought some more about a context cache. 2 Jan 86 Entered the corrections from above. Removed support for the Apollo (the mouse was taken away before Xmas). 3 Jan 86 Visited IST and got some stuff about the Orion. 6-7 Jan 86 VM still doesn't work: crashes after about 170Kbc. 8 Jan 86 Started porting last working VM to Orion. Ran the Cportability tests: everything looks VAX-like. Created an empty shell for BitBlt.c. Removed the include of fcntl.h from IO.c. Aliased malloc to rectangle. Changed an occurence of obtainPointer to obtainPtr in OM.c and also conditionally compiled out some PERQ-dependent stuff to do with bitmaps. Compiled and ran for 290 bc before taking a wrong branch; found the bug straightaway in BC.c; use on nextByte within jump was causing the wrong bc to be fetched. Suspect that I haven't got all the corresponding versions of modules.... After that ran right through all the traces. Next thing to do is to get BitBlt working. 9 Jan 86 Added Orion format to FloatPrims. Worked on IO.c: added Orion cursor setting and positioning, added the setLinked call. The cursor and the mouse on the Orion seemed to be done properly: you can set the mouse co-ordinates without moving the mouse. Parameterised bitmap cacheing for Perq and Orion, as one has 64-bit bitmaps, the other 32. Altered BitMapOf to take a fourth parameter, indicating whether the bitmap to be converted was a halftone. Hacked Mike Wray's BitBlt to do what I needed. Parametrised the pointer to the screen; Perq uses 0, Orion uses theScreen. Hit a brick wall: the first invocation of ConvBitMap, within the first invocation of BitBlt(), was trying to convert a halftone bitmap, and sending malloc() into never-never land. Discovered source of problem: wasn't checking for theScreen in deallocate! BitBlt was OK then until first ScanChars; doesn't seem to work when both src and ht are present. 10 Jan 86 Discovered bug: in ConvBitMap I was dividing by sizeof(WORD) instead of BPW, which meant that the font bitmap was converted to a huge, sparse object. After that, something appeared, but it wasn't the correct text. Looks like the order of bits within words is different. 11 Jan 86 Tried finding bug in PERQ version: no progress 13 Jan 86 More success: found 2 bugs. 1) Was not replacing ip, sp into the active context when returning, hence lastPointer() was wrong when deallocating a context, hence rc's wrong. 2) Was decrementing r.c. of active context before the transaction end when sending a message. 14 Jan 86 VM now runs for quite a long time, but memory is being used up too fast. From the rate I suspect that there is a problem with block contexts. Found another bug: was doing a direct decrement of a ref count when switching contexts, which meant that some contexts werem't being deallocated. However, still doesn't work. 15 Jan 86 Found another manifestation of the previous bug. 16 Jan 86 ...and yet two more! Seems like I should always use c_down() rather than directly decrementing the rc. 17 Jan 86 Fixed a bug in process switching: new processes were being deallocated because of the extra ref.count decrement in addLastLink(). The VM still runs out of memory, but survives a g.c., and can successfully write a snapshot. Checked back in to VAX. Merged mods made at IST into current VM, and also added code for VAX. Crashes at load time: fseek() seems to have changed, and it's not loading properly. 18 Jan 86 Loading is no problem: had created the image using an out-of-date x2m. Seems to work on the VAX: image loads in 6 seconds, and the first 100Kbc take under 8secs on the 8600! Inspected the profile: - most of the time is now spent in send/return code. - Determined the method cache hit rate by subtracting the number of unavoidable calls to lookupMethodInClass (i.e. total # calls to looupM() number of calls to prPerform() and prPerWithArgs()) from those to sndSelToClass(). Came out at 93.26% over 100000 bytecodes Modified the Perq BitBlt to take advantage of the expansion of halftones to 32x32. Didn't work initially; was rather too zealous converting 16s to 32s! Then decided to go the whole hog and convert them to 64x32. 20 Jan 86 Augmented single step with dump of classes, and better printout of the active context. 23 Jan 86 Discovered bug in message send: wasn't counting down the arguments in a new context if there were any temporaries. 24 Jan 86 Visited HLH, met David Small and Tim Robinson 25 Jan 86 Ran two fairly long sessions at the PERQ. The first one was OK, the second had two problems: Life bitblt generated crap, and core dumped while snapshotting. Both were slowly running out of oops (order of 1 per 1000 bytecodes executed). 30 Jan 86 Ran the 4Mbc script on the VAX. Strange! prFlushCache was executed once, and took 1000.03 ms per call! rNil took 211.67 ms per call! The method cache hit rate was 96.6%! 21-22 Apr 86 Tried bringing up VM under PNX 5. Completely killed my machine. Worked OK on Ian's, after initial confusion about version of BitBlt being used. Also, two bugs disappeared: no more crap during Life, and the garbage collection accounting was OK!!! 25 Apr 86 Fixed a couple of bugs in the script playback: 1) Was possibly misinterpreting absolute time words as x/y position events. 2) It seems that the PERQ pads out a struct composed of an unsigned and a short to 8 bytes, when the VAX doesn't. Hence scripts were not being read properly. 6 May 86 Added small context pool. Everything seemed simple, but didn't work---crashed at 2450bc. 7 May 86 Found that I wasn't setting temps to NIL. Changed this, then it seemed OK. In a 1Mbc benchmark, the number of allocate()s fell from 92008 without the small ctx pool to 23165 with, and to 21861 with both small and large. The further fall if block context pools were added would be at most another 3907 calls. The number of refills of the pools was 16 and 1 (small/large). Pool sizes were 200/50 (small/large). Therefore, the small pool caused the number of allocates to drop by 68843 in exchange for 3200, while the large saved 1304 in exchange for 50. 8 May 86 Benchmarked a 4Mbc script on the VAX: took 2'57", (not including image load) with an optimised, non-single step version (but still doing BitBlt in s/w). Works out at 23Kbps. early Jul 86 Recompiled the portable version on a SUN3/160: with single step ran 100Kbc in slightly less time than the 8600! 18 Jul 86 Investigated cannotReturn:. Fails, but actually attempts to send the right message. 15 Sep 86 Started implementing BitBlt on the SUN. Seems straightforward enough. Made a stupid error in precedence when doing a cast, which help me up for a short time, but halftone-only and source-only bitblts seem to work. 16 Sep 86 Fixed the rest of bitblt: had declared Rect as a union instead of a struct! Added code to read from /dev/mouse. 17 Sep 86 Added keyboard driver (raw mode, decoded), and cursor tracking. 4 Feb 87 Started on code to make SUN version run under sunview, based on Michael's input stuff. Had some problems because writing to the screen has to go via pixwin routines but writing to other bitmaps goes via pixrect. 5 Feb 87 Got most of the code going. Decided to force the screen window to not retain a bitmap, and hold a separate screen bitmap. Had a a few problems with input when driving from a script; the standard window menu refused to appear. Got to the stage where everything worked except that the window was not repainted when opened up from an icon. 6 Feb 87 Fixed the repaint problem. Created a version of the VM by removing the D-B collector stuff and all its associated works. This was fairly straightforward by careful use of rcs and diff3. Worked first time! 7 Feb 87 Started implementing snapshot for the SUN3. Got it working OK by using the routines provided in SunView for saving and restoring pixrects. 10 Feb 87 Wrote m1m2 to convert from Manchester 16-bit to 32-bit format. 11 Feb 87 Starting converting VM to 32 bit format. Got to a state where could run up to 65K bc or so, but having problems detecting 31 arithmetic failure on a 32-bit machine. Made a silly blunder early which caused a side-effect in pos32val() (popping one too many items off the stack). 12 Feb 87 Found a genuine bug: was calling addrOfOop in cacheReceiver without testing whether the rcvr was an integer; had got away with this when integers were small, but can't do that with 32-bit ints. Seemed to be OK, so moved to SUN. First problem: was writing image type as 16-bit int, but reading as 32-bit. This worked OK on the VAX, but failed on the SUN. Second problem: had order the half-words within words within bitmaps the wrong way. Ran fine after that, but am still losing oops and core, and it failed when compacting. 13 Feb 87 Investigated the oops and core problem further: found that most of the objects left around were method contexts; still no clue as to why. Fixed the compacter problem after much searching: was incorrectly converting the size field of word objects (halving instead of doubling), and so the compacter fell over its first word object. 16 Feb 87 Found why oops were vanishing rapidly with the simpler 32-bit VM (ie, the one without DB): had an old version of lastPointer that didn't count anythin above top-of-stack when ref. counting. 18 Feb 87 Tried generating a long script (by entering, compiling and testing my coroutine implementation). Unfortunately, the VM crashed occasionally (and unpredictably) when refreshing a browser. Examination of the core dump showed that it was destroying a pixrect within a BitBlt call at the time (mem_destroy). The code here looks so straightforward that it's hard to believe that there could be a bug in it. 27 Feb 87 Inspected code again; found a couple of bugs involving the size of allocated areas for bitmaps: wasn't expanding 16-bit bitmaps into 32-bit at all; everything worked OK despite this. Fixed the bug, but the crash still occurred in the same place. 3 Mar 87 Assaulted st80 with dbxtool. Found the problem right away: when the clipping area and the source region didn't intersect at all was allocating a negative width/height bitmap. Everything seemed to wortk after this. 7 Mar 87 Found a bug in SunView...doesn't set the screen cursor correctly when the number of bytes in a pixrect is not the width of the pixrect rounded up to a multiple of 16. Decided to drop support for Orion and Perq, and simplified BitBlt-related code by *not* widening Forms to multiples of 32 bits. 9 Mar 87 Fixed a bug in prBoot()...wasn't null-terminating the filename string. 10 Mar 87 Fixed a biug in nextInstance()...was returning self everytime, leading to an infinite loop. 16-17 Mar 87 Added simulation code to generate memory references and notication of object creation and deletion. Added static grouping simulation (depth first). 21 Mar 87 Merged simulation and "production" versions, and checked in. 30 Mar 87 Discovered a big image ("windows") had a dangling oop, detected during static grouping. Added code to notify the user of the inconsistency, and patched the image using adb (!) so that it was no longer there. ... lot's missed here Mar 89 Tried porting to SUN 4 .. worked first time. Recompiled with reference counting disabled...went faster, but unreliably, and GC'd every 35s on 4/110! 3 Apr 89 Changed c_down_inner so that no trace was output when nilling out fields of deleted object. 8 Apr - 7 May 89 Added I/O code to run under X11R3. Huge rationalisation, including: - changed style of assignments (asymmetric =) - updated copyright notices - reorganised function names - dispensed with StdHdr.h and KeyMap.c - split machine-dependent parts off into separate files - updated IO.doc - fixed suntools and sunraw version to work on colour frame buffers (X11 version seems too hard...) - tested and improved comment merge facility Checked in at 4.1. Remaining problems: colour X, -O4 version causes memory fault when quitting. 11 Apr 91 Recompiled for X11R4. Fixed bug (actually due to incorrect assumption) cause all-white pixmaps to be uninitialised (random garbage). 11 May 91 Wrote some documentation and tidied stuff up to send to Ed Gehringer, 20-21 Jun 91 Fixed generic version so that the snapshot OT format was compatible with X11. Added old receiver to method trace (for Rhod). Made generic display size same as default SUN X11 display size. 2 Sep 91 Added option to trace classes of receiver and args, and old receiver (for Rhod). 22 Oct 91 Found and fixed three bugs: 1) Use of realsize() rather than size() meant front-panel inspector printed too little out, and 'd' and 'i' trace records had ridiculous sizes. Changed to use size(), removed realsize(). 2) Call to instPtrs in prNew was multiplying size by sizeof(WORD), making objects 4 times too large. I wonder what results this changes... 3) (after many hours searching) found calls to storeByte in pos32int using indices 0,1,3,4... aaaarrrrgggghhhh! 6 Nov 91 Rhod had problems with the 'm' simulator records: integer receivers appeared to have a class other than integer! Traced to statements out of order in executeMethod() [trace_send being called *after* a quick instance load had deposited a new value on the top of the stack]. 11 Nov 91 More problems: this time the trace data for a primitive was output after the primitive executed. This meant (a) most of it was junk, and (b) sometimes an object would appear to be reclaimed *before* being sent a message! Fixed (mainly) by reordering in executeMethod(). [update not sent to Ji-En.] 20 Nov 91 Add 'B' trace record for Rhod, outputting receiver of ctx returned to. 23 Nov 91 Added extra field to B record. 2 Dec 91 Added a 'k' record for the class of initialised and created objects. 28 Jan 92 Added a 'n' record for the class of the returned result from a context, and whether the result==self. 30 Jun 92 Modified ref-counting code to avoid emitting access references when deallocating object. 2 Jun 92 Added g tracing option to determine depths of static grouping. Fixed parse_opts: expected arg after -g (took ages to find this!) 27 Jul 92 Ported VM to HP 750. Fixed two bugs in non-sim version: in both eJump and prEquiv the undefined order of side-effects could cause problems (and did, in eJump). After that, ran OK (actually, ran *bloody* fast!). Times: 8.5M bootx.script, 59.6s real (57u, 0.5s) 19.6M windows.script: 1:51.5s real 1:41.7u, 0.9s 24 Sep 92 Tried Purify on the sparc version: no errors! 11,12 15 Aug 94 Fixed X code so that it works on colour displays. Lots of messing about; it's hard to find out when you've used the wrong parent for a graphics context! Fixed up makest with a -svr4 option. Started using GCC under Solaris -- strange bug using cc; looks like compiler error when calling ftime in IO.c (passed address of Time_now; ftime gives bus error). 30 Aug 94 Fixed bug in integer shift prim: shifting by -32 or more was relying on undefined case in C (shift right of 32 was not zero). Found by Urs, by printing 33333333333. 21 April 95 Filed in Richards. Found that "0 size" caused a segmentation fault because the size prim doesn't handle int receivers. Easy fix. Richards takes 55s on SS-10, almost the same as GNU Smalltalk 1.1.1. In constrast ParcPlace takes 1300ms, and Smalltalk-in-Self 550ms.