Send mail to the CREATE web master
Index
Date: 97 Feb 01 12:24:01 pm
From: CarlGWatts@AppliedThought.com (Carl G. Watts)
To: johnson@cs.uiuc.edu (Ralph E. Johnson)
Cc: squeak@create.ucsb.edu
Subject: Re: Process suspend doesn't properly deal with Semaphore wait
At 3:49 AM 2/1/97, Ralph E. Johnson wrote:
>When I teach about allInstances, I *always* tell people it is Deep Magic,
>to be used only during debugging, and should never be used in an application
>program. I suppose it would make sense for the method to say that, too.
>That is a good use for a comment!
Yes, there are a lot of methods in Object that should be documented for newbies to describe their proper uses. "respondsTo:" and "isKindOf:" are two other methods that get overused by neophytes not understanding their limitations and appropriate uses.
Maybe I'll write up some new comments for several of methods in object that more describe their appropriate uses (keeping in mind a newbie audience) and submit them to the Squeak team.
Carl Watts
Date: 97 Feb 01 1:40:26 pm
From: Stefan Matthias Aust <sma@kiel.netsurf.de>
To: squeak@create.ucsb.edu
Subject: Forth in Smalltalk
I looked for some interesting references to Forth in the Web and found a
little Forth written by Jack Woehr (jax@cygnus.com) in Digitalk's ST/V. I
became interested and ported the source to my VisualWorks 2.5 to play around
with it. I orignally planed to port it to Squeak, too, but because it lacks
to simplest features I stopped.
Below is my changes file. If anybody is interested and wants to continue
this project, I can send either the original ST/V (you won't see them,
they're ugly :-) or my VW sources (~20K). I've forgotten, where I found the
source :-(
Be warned, the Forth is very primitive and any kind of loop or condition
word is missing. It has no reflective features, doesn't simulate the heap
correctly and treats literals wrongly.
My changes:
- All classes have "Forth" prefix now.
- Code reformated and some pieces changed for better understanding.
- Unportable ST/V window stuff replaced with unportable VisualWorks stuff.
- InputStream and Stack simplified and adapted to VW (probably portable).
- String system extension isForthNumber replaced with InputStream>
isForthNumber:. Don't spread code through the system without need.
- _global_ FORTH variable converted to Task's class variable. No globals!
- ForthPrimitve is now subclass of ForthContant to share more code.
- Some more primitives added: ( * / + - < = >
At this time, I noticed, that numbers are treaten wrongly at compile time. A
forth system should emit a special LIT word together with the literal
instead of a NOOP. The whole compile/execute stuff is broken, I think. What
a pity.
bye
--
Stefan Matthias Aust // Too much truth is unhealthy...
http://www.kiel.netsurf.de/users/s/sma/
Date: 97 Feb 01 4:45:32 pm
From: Maloney <johnm@wdi.disney.com>
To: CarlGWatts@AppliedThought.com (Carl G. Watts)
Cc: squeak@create.ucsb.edu
In-Reply-To: <v02130501af18729a73cb@[199.170.109.113]>
Subject: Re: Process suspend doesn't properly deal with Semaphore wait
> If only the debugging method 'allInstances' returned ONLY referenced
> (reachable) objects (which it doesn't seem to do in most Smalltalks
> unfortunately (for some admittedly reasonable implementation reasons))
You can have your wish for the mere cost of doing a full GC right
before calling allInstances! Compare:
Point allInstances size
with:
Smalltalk garbageCollect. Point allInstances size
The GC isn't bundled into the primitive because it does take a few
hundred milliseconds and often you don't really need to exclude the
unreachable objects.
-- John
Date: 97 Feb 01 10:20:25 pm
From: stp (Stephen Travis Pope)
To: CarlGWatts@AppliedThought.com
Cc: squeak@create.ucsb.edu
Subject: Re: Process suspend doesn't properly deal with Semaphore wait
Just a nit: "respondsTo:" and "allInstances" are useful tricks
that can safely be taught to neophytes with the appropriate words
of caution. "isKindOf:" is a grave mistake, and should be treated
as such.
stp
_Stephen Travis Pope, Center for Research in Electronic Art Technology
_(CREATE), Dept. of Music, U. of California, Santa Barbara (UCSB)
_Editor, Computer Music Journal (CMJ), MIT Press
_stp@create.ucsb.edu http://www.create.ucsb.edu/~stp/
Date: 97 Feb 02 7:23:19 am
From: kgarrels@rhein-neckar.netsurf.de (Kai Garrels)
To: Squeak@create.ucsb.edu (Squeak)
In-Reply-To: <32F00883.760@netins.net>
Subject: Re: Merging Forth and Smalltalk
> Here is something I just posted to comp.lang.forth.
>
> Any comments from the Squeak side of the aisle would be appreciated.
>
> Subject: Merging Forth and Smalltalk
> Date: Wed, 29 Jan 1997 19:54:32 -0600
> From: Paul Fernhout <kfsoft@netins.net>
> Organization: Kurtz-Fernhout Software
> Newsgroups: comp.lang.forth
>
> Forth is really neat, and Smalltalk is really neat, and I keep thinking,
> if I could only put them together somehow...
There is a system for macs calles MOPS that implements this idea to some
extent.
I think the Smalltalk footprint comes from the neat things included
(huge class lib, browsers, debugger....)
Bye,
kai
--
sig 1
Date: 97 Feb 03 8:07:39 am
From: Paul Fernhout <kfsoft@netins.net>
To: Stefan Matthias Aust <sma@kiel.netsurf.de>
Cc: squeak@create.ucsb.edu
Subject: Re: Merging Forth and Smalltalk
Stefan -
Thanks for all your informative posts on this topic..
I especially liked your sketch of an implementation of Smalltalk in
Forth. You *must* of been thinking about this before to be able to
write such a complete analysis in one email.
By the way, I found a thread related to this from Dec 13 1996:
"Ist SmallTalk Forth" using DejaNews. It is in
de.comp.lang.smalltalk by Klaus Heinisch. My German
is a bit rusty, but basically it appears to be someone having an 'aha'
experience seeing the similarities between the Forth and Smalltalk, as
well as two followups on this.
For information on Forth standards, a good URL to start looking at is:
http://www.taygeta.com/forth.html
You might also find this amusing, a forth for the ARM:
ftp://ftp.uni-stuttgart.de/pub/systems/acorn/riscos/lang/forth/forthmacs
Or as two people have mentioned, there is the PD MOPS system, currently
on the Macintosh. I for one would prefer to keep the two languages
seperate - using standard FORTH for low level primitives and as an
intermediate language for new languages and standard Smalltalk for GUI,
tool building, and everything else.
Thanks for your posting about a Forth written in Smalltalk.
I too wrote a Forth-like interpreter for Smalltalk in VisualWorks+ENVY
about a month or so ago to try out the idea (it only took a few hours,
but it leaves out key Forth features like BUILD>DOES>). I'll see if I
can port it to Squeak sometime. I have two versions. Both define
Forth-like sequences of words using arrays which are sent to the VM to
be interpreted; the VM includes a dictionary of such arrays to use for
defining words. One sends all words to the VM instance which supports
some Forth words; the other (a minor variant) sends keywords as
perform:with: messages to previously stacked Smalltalk constants,
globals, or the vm using previously stacked arguments. The language only
needs one special word 'meta' which says push the next symbol on the
stack instead of dispatching it.
The result of doing this is I realized: I'd much rather program in
Smalltalk than Forth. The major point to doing Forth is speed (and
possibly simplicity of maintainence for a VM or use for intermediate
code), which requires a complete Forth implementation with its own stack
running its own interpreter.
Fortunately, there are many PD or easily distributable Forth
implementations. Usually they lack development tools or Windowing
interfaces - but Squeak's already got that. Right now I'm looking at
Timbre (a Forth system including a neat rule based parser - although I'm
still waiting for the author to tell me if I can use it in Squeak). It
looks like Timbre could be grafted onto Squeak with very little work
(mostly writing the Smalltalk ForthVM class and a few primitives) as it
generates itself in C and already runs on the PC, Mac, and HP-UNIX. It
of course wouldn't have the performance of a native Forth system.
John Maloney has suggested:
> One approach might be to use Forth as an intermediate language
> generated via translation from a subset of Smalltalk,
> much as C is generated now.
He said this would let you code primitives in Smalltalk as now, and have
a choice of genrating Forth right now for a speedup, or later compiling
to C for maximum performance.
On Speed:
A fairly complete description of all Forth threading techniques and
their relative speeds can be found at:
http://www.complang.tuwien.ac.at/forth/threaded-code.html
My figures for Forth speed currently are based on some DejaNews
comp.lang.forth postings, and are:
* Max current Forth speed 1/2 C - based on bigFORTH estimate
* Typical Forth speed - 1/7 C - based on gforth (written using GCC and
some of its special features not normally found in a C compiler) see:
http://www.informatik.tu-muenchen.de/~paysan/html/gforth_85.html#SEC89
[Unfortunately gForth is GPL'd and so can't be used in Squeak without
also contaminating it for use in products. Actually, if Squeak was
GPL'd I'd just about lose all my enthusiasm for it.]
* Typical forth in C speed - 1/14 C - based on cForth being about 1/7
the speed of the fastest benchmark (toy), and assuming Toy is 1/2 C
speed. Also based roughly on Win32Forth being slightly slower than
gForth (1/7 C), and cForth is slower than Win32Forth (in one case about
50%).
Since I don't have any experience with any of these systems, and I am
only looking at a few benchmark references, I would take all my Forth
efficiency figures with a grain of salt.
So, this means that if Squeak is currently about 1/60 C, then primitives
in Forth would give about a 5X speed up. Such primitives would still
take a 14X hit over straight C. With an optimized Forth, we would be
looking at a 2-7X hit.
Of course, simple primitives which are composed of simple words that are
basically inlined assembler would run at near C speed (ignoring the C
compilers optimizing ability, which might be significant for high end
CPUs). Again, it depends on exactly what you are doing. If FPU calls
for numerical primitives swamped the overhead of the threading, one
might get near the speed of C from Forth. I'm not sure of these
relative times of FPU call vs. threading overhead.
Clearly, the overhead rate would be higher for byte manipulation,
although again it depends on the task, and on whether the lowest level
words were highly optimized or not. Many Forths allows one to easily
inline assembler, so for example a BitBlit primitive might be composed
of several Forth words, only a couple of which might be hand coded
assembler of a few operations each. If these hand coded primitives did
the bulk of the inner loop work, then the overhead again might not be
that bad. (Note that an inlined assembler option generally isn't
available in portable Forth in C).
The key thing to remember is that Forth developers are very concerned
about these speed issues for threaded code, and have experience with
them on a wide range of CPU architectures, and it would be nice to
leverage all their work (or at least, their knowledge).
At this point, I'm starting to think that speed may not be the issue
that makes this worth doing over compiling primitives in C (unless one
builds in a non-portable native Forth). Providing an intermediate
language for putting other languages into Squeak may be the stronger
reason (for me at least) to want to do this. Because of Squeak's
current language overhead, it doesn't make the fastest system for
embedded languages. An intermediate Forth language might give it this
capability, and allow one to write the language translator in Smalltalk.
Someone recently posted something related to this in comp.lang.Forth
(Subject: "In the WIlderness") mentioning their interest in using a PD
Forth to develop application specific command languages.
-Paul Fernhout
kfsoft@netins.net
========================================
Download a public beta release of our garden simulator at:
http://www.gardenwithinsight.com
Date: 97 Feb 03 9:27:35 am
From: Paul Fernhout <kfsoft@netins.net>
To: Hans-Martin Mosner <hmm@heeg.de>
Cc: squeak@create.ucsb.edu
Subject: Re: Merging Forth and Smalltalk
Hans-Martin -
Thanks for your analysis of the different speedup alternatives available
for Squeak. I too want a fast Squeak, and know that Squeak-Forth
probably won't ever be as fast as dynamic native compilation of
Smalltalk (especially with types). I'm just trying to find a solution
to speedup Squeak that fits in my (or our) limited spare time, which is
our greatest constraint, as you pointed out.
I also recognize that a Forth solution that isn't as good as another
might undermine Squeak's improvement and general adoption, in the sense
that the good is often the enemy of the best, and we might then never
get around to something better (like I hear Ian is trying to do...)
With that said, I'm going to try to persuade you to reconsider Forth as
a language to embed in Squeak despite it's seemingly awkward syntax, for
these reasons:
* it has a self reflective elegance (like Smalltalk)
* it has a simplicity and completeness (like Smalltalk)
* it is written (mostly) in itself (like Smalltalk) and so it can be
easily bootstrapped and can be fairly portable
* it can be used to generate C (like Smalltalk) for portability
* it can easily (i.e. a weeks work or so for someone who knows how to do
it) be made to run really fast (i.e. close to compiled C speed) on any
hardware (using a few key words written in assembler)
* it has a tradition of being made to run on OS-less machines with
fairly little effort (i.e. days...) using its block file system and
editor. (Gee, doesn't Newton FLASH RAM work with *blocks*?)
* it would be a good development system on the Newton by itself as a
NewtonScript complement (because of its small footprint and tradition of
being developed in small screenfulls).
* it could be used as a mostly portable intermediate code, which one
could use to develop arbitrary languages under Squeak with arbitrary
performance. So, if I wanted to use Squeak to develop tools for
numerical computation (without message passing, stack frame, gc, or type
checking overheads), I could generate Forth rather than Smalltalk.
The alternative is to invent my own intermediate language (reinventing
the wheel) or compile to native code (reinventing and hard).
* a Smalltalk VM written in Forth might be a very malleable thing for
testing OO notions and adding on other language support (like LISP,
PROLOG, Python, BASIC, etc.), like Ian's suggestion for a general object
engine
* it has an interested and experienced technical community of thousands
of engineers (many who do Forth partially as a hobby for things like
Robotics). This is the same reason I prefer using Smalltalk over a
homebrew language, since it has more people interested in it.
How many people have an intimite knowledge of any particular Smalltalk
byte code set? If people are going to study the VM to change it, they
need to learn a lot anyway, so why not Forth?
* it has hardware (Forth CPUs, first developed by Chuck Moore) that run
it very quickly (over a decade before the Java chip), and so would
provide another alternative for putting Squeak on a PDA using such a
chip. Since the ARM core is usually tailored by the distributors to
make the final CPU, Apple could add Forth right into the ARM processor
to make Squeak->Forth->SpecializedStrongARM something that would have
incredible performance on a Newton.
* For headless apps, or apps that ran as applets and talked to someone
elses windowing system, one could develop projects in Squeak, and then
produce very small executables generated entirely in Forth.
* it could possibly replace Java or the Java VM with the right words
* one might be able to easily extend the Squeak debugger so it
transparently debugged from Smalltalk into a Forth primitive.
* it provides a ready intermediate language for Smalltalk experiments to
add types. If Smalltalk knows the types for a '*' message, it can do
the operation with the correct Forth words.
* it provides a way to eliminate C dependency for Squeak (at a cost of
more difficult ports).
* it provides a way to write primitive code close to the hardware (say
for robotics or music), which while unsafe, is likely to be safer than
writing in assembler or even C, because it can be tested interactively.
Possibly, one could use a safe Forth VM for development, and then give
the code to an unsafe but faster Forth VM for deployment.
Of course I think Forth has problems: it has an awkward syntax compared
to Smalltalk (although that awkwardness passes with experience), and it
can be very dificult to read and understand someone else's code (which
probably doesn't get much better with experience), and it could easily
corrupt an image or crash the machine. I'd prefer Forth if it used all
lower case, and if words more reflected their expected stack arguements
and results. But, it's so much easier for me to start using it as is,
and then maybe later I could pretty it up.
Also, Forth does have other disadvantages mentioned here and elsewhere:
* Byte codes are more compact than Forth. One could hope this could be
worked around - perhaps with an intermediate table and a way to have
byte code strings contain variable length address references (one or two
bytes indexes as needed into a jump table to Forth code)
* Fancy CPUs require sophisticated compilers and optimizers to get
maximum performance (and common C compilers usually have these
features). I don't see any way in practice to get around this
situation, other than to hope Forth vendors write such compilers, and
make Squeak Forth portable enough to use them. On the plus side though,
it is easy to make hardware that runs Forth really fast, thus avoiding
the compiler issue, and such chips already exists for use in embedded
systems. It might even take only a few instructions to add to the
Pentium to get it to be an ideal Forth chip. Intel did it for MMX.
-Paul Fernhout
kfsoft@netins.net
========================================
Download a public beta release of our garden simulator at:
http://www.gardenwithinsight.com
Date: 97 Feb 03 10:13:47 am
From: guzdial@cc.gatech.edu (Mark Guzdial)
To: Squeak@create.ucsb.edu
Subject: Music in Squeak - Novice Q's
Based on the recent thread on the Forms Editor, I'd like to start a new
novice thread, on music in Squeak.
Before Christmas, I tried to implement the round "Christmas is Coming" in
Squeak. I built three methods to play each of the bars of the song, and
tested to make sure that at least one of the methods (firstBar) did in fact
play correctly (using namedNoteSequenceFrom:). Then I tried to write a
method which played all three bars in one voice, rested for a bar then
played all three in a second voice, and a third voice that rested for two
bars then played the song -- a very simple start on a round. However, all
I got was silence (no error messages), and I couldn't play anything after
that! No sounds emerged from Squeak at all!
Here are my questions:
(1) It seems that if you feed garbage to the Sound Player process, you're
sunk forever after. Is there someway to reset the Sound Player after a
bug?
(2) What is the "pan:" option in the "add:pan:" method? I made up my
inputs based on the Bach fugue, but I really don't understand what it
means.
(3) Finally, I've included a fileOut of my attempt below. If anyone has
any suggestions or notes any glaring bugs, I'd appreciate having them
pointed out.
Thanks!
Mark
'From Squeak 1.18 of December 12, 1996 on 24 December 1996 at 12:04:20 pm'!
!AbstractSound class methodsFor: 'christmas example'!
christmasIsComing
"Trying to do a three voice round"
^ MixedSound new
add: (PluckedSound namedNoteSequenceFrom:
(PluckedSound firstBar) , (PluckedSound secondBar)
, (PluckedSound thirdBar))
pan: 200;
add: (FMSound namedNoteSequenceFrom:
(FMSound restFor: 1) , (FMSound firstBar) ,
(FMSound secondBar) , (FMSound thirdBar))
pan: 400;
add: (PluckedSound namedNoteSequenceFrom:
(PluckedSound restFor: 2) , (PluckedSound firstBar)
, (PluckedSound secondBar) , (PluckedSound thirdBar))
pan: 600.
!
firstBar
^ #(
(c5 0.50 248)
(g4 0.375 248)
(g4 0.125 248)
(c5 0.25 248)
(c5 0.50 248)
(c5 0.25 248)
(c5 0.25 248)
(c5 0.25 248)
(b4 0.25 248)
(a4 0.25 248)
(g 1.00 248)
).
!
restFor: numBars
| restLength |
restLength _ numBars * 16.0.
^ Array with: (Array with: 'rest' with: restLength)!
secondBar
^ #(
(rest 16.0)
(c5 0.375 248)
(c4 0.125 248)
(c4 0.25 248)
(d4 0.25 248)
(e4 0.25 248)
(c4 0.25 248)
(e4 0.25 248)
(g4 0.25 248)
(a4 0.50 248)
(g4 0.25 248)
(f4 0.25 248)
(e4 1.0 248)
).
!
thirdBar
^ #(
(rest 32.0)
(e4 0.375 248)
(f4 0.125 248)
(e4 0.25 248)
(d4 0.25 248)
(c4 0.25 248)
(c5 0.25 248)
(g4 0.25 248)
(e4 0.25 248)
(f4 0.50 248)
(g4 0.25 248)
(b3 0.25 248)
(c4 1.00 248)
).
! !
--------------------------
Mark Guzdial : Georgia Tech : College of Computing : Atlanta, GA 30332-0280
(404) 894-5618 : Fax (404) 894-0673 : guzdial@cc.gatech.edu
http://www.cc.gatech.edu/gvu/people/Faculty/Mark.Guzdial.html
Date: 97 Feb 03 10:41:21 am
From: Dan Ingalls <DanI@wdi.disney.com>
To: Squeak@create.ucsb.edu
In-Reply-To: <Marcel-1.08-0130173654-927KL&V@goldskin.interval.com>
Subject: FYI: Sharing in Squeak
In designing a port of the old SystemTracer forward to Squeak, the question=
arose to what degree objects in a typical Squeak image are shared (ie how=
many pointer there are to each object). To answer this question I=
implemented the necessary dictionary, and here are the figures...
SortedCollection (1->26 2->8477 3->19019 4->9773 5->3846 6->1805 7->1365=
8->1225 9->920 10->797 11->586 12->403 13->283 14->214 15->181 16->134=
17->109 18->94 19->77 20->58 21->45 22->53 23->28 24->34 25->26 26->29=
27->15 28->14 29->20 30->23 31->18 32->22 33->9 34->10 35->13 36->6 37->9=
38->11 39->10 40->11 41->3 42->4 43->8 44->9 45->14 46->6 47->11 48->9=
49->6 50->3 51->6 52->1 53->10 54->4 55->7 56->4 58->2 59->5 60->1 61->5=
63->5 64->1 66->5 68->5 69->3 70->7 71->3 72->1 73->4 74->2 75->1 76->3=
77->4 78->2 80->1 81->4 82->2 83->2 84->3 85->5 86->2 88->1 90->1 91->2=
92->2 94->1 95->1 96->2 97->1 98->2 99->3 101->1 103->2 104->1 107->1=
111->1 113->1 114->2 115->1 118->2 119->1 121->2 127->1 129->2 131->1=
132->1 133->1 134->1 135->1 142->1 143->1 147->1 148->1 152->2 157->1=
158->2 166->1 169->2 175->1 179->1 184->1 189->1 191->1 193->3 203->1=
208->1 217->1 221->1 232->1 233->1 245->1 250->1 258->1 262->1 263->1=
270->1 330->1 336->1 363->1 438->1 738->1 796->1 1051->1 75142->1 )
NOTES:
1. All entries of the form (number of pointers to an obj) -> (number of=
objs with that many)
2. All counts are higher by 1 than they should be owing to an extra=
reference from the enumerating structure. =20
3. The 26 objects that appear to have no pointers to them are objects which=
got stored over by other temporary values in the process of the enumeration=
=2E
4. Presumably nil is responsible for the blip at the end of the curve.
Date: 97 Feb 03 1:11:51 pm
From: Maloney <johnm@wdi.disney.com>
To: Paul Fernhout <kfsoft@netins.net>
Cc: squeak@create.ucsb.edu
In-Reply-To: <32F610AE.5353@netins.net>
Subject: Re: Merging Forth and Smalltalk
>So, this means that if Squeak is currently about 1/60 C, then primitives
>in Forth would give about a 5X speed up. Such primitives would still
>take a 14X hit over straight C. With an optimized Forth, we would be
>looking at a 2-7X hit.
A threaded-code Squeak might be only 15 times slower than C.
This would weaken the speed argument for a non-optimized Forth. It would
also make embedded languages more feasible.
Another approach to implementing embedded languages is to translate
the language to Smalltalk bytecodes. If there is a good match, then
the embedded language might not be much slower than Smalltalk itself.
A final point is that, depending on your application, the speed of an
embedded language may be less of an issue than one might think. Hypertalk
is literally 1000's of times slower than C, and I believe that Tcl is in
the same ballpark. Yet these languages have found many useful applications
in rapid GUI construction. Likewise, for teaching purposes, even
a slow Lisp, Prolog, or APL written in Smalltalk could be quite
adequate for conveying the principles of the given language and
perhaps teaching about its implementation as well.
-- John
Date: 97 Feb 03 1:15:10 pm
From: Maloney <johnm@wdi.disney.com>
To: guzdial@cc.gatech.edu (Mark Guzdial)
Cc: Squeak@create.ucsb.edu
In-Reply-To: <v02130513af1b8f9f9b1f@[130.207.3.225]>
Subject: Re: Music in Squeak - Novice Q's
Mark,
>Here are my questions:
>(1) It seems that if you feed garbage to the Sound Player process, you're
>sunk forever after. Is there someway to reset the Sound Player after a
>bug?
I don't think your problems have to do with having fed bad input to the
SoundPlayer process. We found an intermittent problem with sound output
on the Mac in late December. It turns out that if SoundManager has not
already been loaded when you first try to output sound from Squeak, the
Mac attempts to load it into Squeak's application heap. Unfortunately,
there isn't enough room for it because the Smalltalk object memory has
taken most of the available space. Increasing the applications memory
partition doesn't help, because Squeak just uses that memory to enlarge
its object space. The workaround is to put "SoundManager" in the
extensions folder of your system folder.
The bug has been fixed, but won't go out until the next Squeak release.
However, I'll send you a copy of the current (fixed) VM. I can also
tell you how to change the source file of the released VM to leave
enough memory for the SoundManager if you are building your own VM's:
increase the "reservedMemory" in sqMacWindow.c to at least 130000.
Sorry about this; I had the SoundManager in my extensions folder so
I never had any problems. This is one of those little Mac programming
"gotchas" where what you don't know CAN hurt you!
>(2) What is the "pan:" option in the "add:pan:" method? I made up my
>inputs based on the Bach fugue, but I really don't understand what it
>means.
The "pan:" parameter controls left-right panning in stereo mode.
Let me know when you get it working. Sound is really fun!
-- John
P.S. I tried your "Christmas Is Coming" round. Very cute! I needed
to change the constant in "restFor:" from 16.0 to 4.0 and eliminate
the leading rests from the note sequence for each round part, but
then it sounded great!
Date: 97 Feb 03 4:50:04 pm
From: Dan Ingalls <DanI@wdi.disney.com>
To: Paul Fernhout <kfsoft@netins.net>
Cc: Squeak@create.ucsb.edu
In-Reply-To: <32F00883.760@netins.net>
Subject: Re: Merging Forth and Smalltalk
=46olks -
I have been folowing this thread with interest, but no free time to make a=
reasoned response. I first got into forth about 18 years ago [when ToysRUs=
unloaded the Commodore 64 for about $40 and you could get a Forth cartridge=
for another $20]. Then about 18 months ago I got interested again when I=
realized you could build a whole Forth engine in an FPGA (field-programmabl=
e gate array). I thought that, with a bit of tweaking (like tagged=
integers), this could actually become a mean Smalltalk kernel.
So I have a lot of sympathy with the notion of Forth being a language for pr=
imitives.
Let's step back for a few minutes, though, and analyze what is so neat about=
forth...
By adopting Polish syntax, and then getting in bed with the stack,=
generation of threaded code becomes almost trivial. As a result of this, a=
compiler can be written in just a few pages of Forth. As a result of this,=
a Forth *development system* can run in environments where few run-time=
systems will fit.
At the same time there are a number of things that are not so nice, such as=
ugly stack munging in place of temp and arg names, and numerous possible=
ways to screw yourself (but, Hey, that's what primitves are all about).
Now let's return to Squeak. Squeak's VM is all written in a=
Pidgin-Smalltalk that really only uses integers and arrays, so that it can=
be translated to C. With the music primitives, John made a foray into a=
more lightweight extension to the VM by making it easier to migrate a=
single Smalltalk method, written in this style, to C and thus to high=
performance (see FMSound mixSampleCount:...). The upside is that a=
Smalltalk programmer who knows what he is doing can get high performance=
without leaving his native language. The downside is that, although it's=
still all Smalltalk, you have to deal with all the mechanism needed to=
rebuild the VM in C, and this is daunting, if not downright forbidding, to=
most of us.
So, here is my take on the Forth/Smalltalk synergy (this is very much like=
John Maloney's suggestion, except that it eschews the use of Forth, going=
directly to threaded code):
1. Walk tall and Talk Small. In other words, lets keep all the code in Sma=
lltalk.
2. Use Squeak's existing compiler to generate portable threaded code for=
primitives. Shouldn't be more than a page of code.
3. Write an interpreter for the portable threaded code. This, too, should=
be about a page for the "inner interpreter" plus a couple more pages for=
the Forth primitives which, in this case, would include things like=
instance variable access, STInteger conversion, etc. This part can also=
all be in Smalltalk, but it would be translated to C and compiled as part=
of the VM.
What would one of these primitives look like?
It would look just like Smalltalk (except that it would be the Pidgin=
subset) when you are debugging it. Then, when you're ready for the=
afterburner, you add the line
<primitive>
at the top. This tells the ST compiler to check for Pidgin subset and=
generate threaded code into a literal (as Tim Rowledge and Jecel Assumpcao=
suggest). It also sets a magic number in the primitive field of the method=
which starts the threaded interpreter.
How does this compare with the other approaches?
vs Primitives in Forth:
It's still a one-language system, the Squeak philosophy.
vs C translation (as in music primitives):
No need to recompile VM. 1 second turnaround. 5-10x slower execution, but=
5-10x faster than Smalltalk. Note also that your code is in Pidgin=
Smalltalk. You can always take it through the VM compile cycle, and get=
*real* C speed, again from the same Smalltalk.
vs JIT, or Dynamic Translation:
This approach is only applicable to primitives (leaf methods that don't call=
other ST methods). It is a sub-language that is not polymorphic, not=
garbage collected, not bounds-checked. And you're glad of it. It can run=
within 2-4 times the speed of C. JIT, on the other hand, is applicable to=
the entire system. It can bring all Smalltalk code to within 5-15 times=
the speed of C.
Date: 97 Feb 04 7:36:43 am
From: Dan Ingalls <DanI@wdi.disney.com>
To: Squeak@create.ucsb.edu
Subject: What's up
=46ellow Squeakers -
It's over a month since we've said what's going on here, so I thought it=
would be useful to tell you what I can. Here's a brief summary of how it=
looks from 2 feet behind the screen:
1. We ARE getting sockets running in Squeak. Way cool.
2. We are preparing a major redo of all Squeak graphics along the lines of=
Morphic and Fabrik, for those of you who know these. Lotta work, but we=
think you'll like it.
3. We will probably convert the entire system to the new graphics model=
(event-driven as well) and release this as 2.0.
4. Since some people might consider 2.0 a parting of the ways (bye-bye to=
MVC as we know it), we will probably try (that's a double fuzzy) to release=
a 1.9 at the same time which would be like 1.8 with all useful updates,=
with the new graphics system also included but unused and easy to get rid=
of. 2.0 would be made from it simply by filing in all the current apps=
converted over, and throwing out MVC.
5. If everything works out, we are arranging with some outside help to do a=
simple, portable dynamic translator for Squeak. This should expand=
Squeak's domain of practical application, both to more challenging=
computations and to less powerful machines.
That's about it. We'll try to keep up with various requests and bug=
notices, but we're hoping to get a couple more months out of 1.18 before=
the 1.9/2.0 release.
Yours, on behalf of the Squeak Team,
- Dan
Date: 97 Feb 04 9:09:51 am
From: "David N. Smith" <dnsmith@watson.ibm.com>
To: Dan Ingalls <DanI@wdi.disney.com>
Cc: Squeak@create.ucsb.edu
In-Reply-To: <v0300780daf1c80285440@[206.16.10.79]>
Subject: Re: What's up
At 10:49 -0500 2/4/97, Dan Ingalls wrote:
>Fabrik
Been meaning to ask if Fabric ran on Squeak, and, if so, if you had any
intensions of releasing it as a non-trivial example app or something.
Dave
_______________________________
David N. Smith
dnsmith@watson.ibm.com
IBM T J Watson Research Center
Hawthorne, NY
_______________________________
Any opinions or recommendations
herein are those of the author
and not of his employer.
Date: 97 Feb 04 10:14:07 am
From: Stefan Matthias Aust <sma@kiel.netsurf.de>
To: squeak@create.ucsb.edu
Subject: Re: Merging Forth and Smalltalk
Hi!
>I especially liked your sketch of an implementation of Smalltalk in
>Forth. You *must* of been thinking about this before to be able to
>write such a complete analysis in one email.
Well, some times ago I wrote an article in comp.lang.smalltalk showing a
Smalltalk VM in Smalltalk (only to realize, that this was already done in
the (famous) Blue Book, I've never seen before that day :-) and these
experiences were easy to translate. Frankly, that was the first time after
about 12 years, I thought about Forth again. And I now noticed (again), that
it is still a very interesting language. After one weekend of
internet-research about Forth I'm now convinced that doing a VM for
Smalltalk in Forth is a good idea and I'm ashonished that obviously nobody
has tried this yet.
>By the way, I found a thread related to this from Dec 13 1996:
>"Ist SmallTalk Forth" using DejaNews. It is in
>de.comp.lang.smalltalk by Klaus Heinisch. My German
^^
de.comp.lang.forth. Unfortunately, ST hasn't an own newsgroup in Germany :-)
>is a bit rusty, but basically it appears to be someone having an 'aha'
>experience seeing the similarities between the Forth and Smalltalk, as
>well as two followups on this.
Klaus told (Dec 13 1996) about visiting a lecture about Smalltalk, and
talking before to some Smalltalk enthusiasts who told him about "unique
features" of Smalltalk I said he already knew from Forth. He draw the
conclusion, that both languages are quite similar and that it seems a good
idea to use Forth as a kind of assembly language to build a Forth from.
Bernd (from Munich technical university) pointed out his view of Smalltalk
and some differences about Forth and Smalltalk (I'm afraid, he's too much a
fan of Forth than he'd be able to judge Smalltalk correctly :-) He then ran
down Microsoft and mentioned gforth-0.2.0, which shall have OO features.
Egmont then rave about Forth's ability to allow programmers all kind of
programming - both structured and unstructured - Smalltalk being too
restricting. While the stack machine is concept of Forth, Smalltalk's VM is
only an implementation detail was his statement. Hating C++ must be another
thing, Forth- and Smalltalk-lover have in common. Finally, he was telling
some facts about the history of Smalltalk.
Unfortunately there was no direct answer to the question, whether someone
has or wants to try the fussion of Forth and Smalltalk.
>Or as two people have mentioned, there is the PD MOPS system, currently
>on the Macintosh. I for one would prefer to keep the two languages
I found this reference, too. The manual stats that experienced Forth and
Smalltalk programmers should be careful not to assume anything because it
might be different. However, I haven'd browsed through it yet. I still
wounder, if any of the OO-Forth versions (I also found a very interesting
paper from Andras Zster "An Assembly Programmer's Approach to
Object-oriented Forth) has a real dynamic memory management system with
garbage collector.
>seperate - using standard FORTH for low level primitives and as an
>intermediate language for new languages and standard Smalltalk for GUI,
>tool building, and everything else.
I, too, would see Forth as an implementation vehicle and wouldn't want to
mix both languages up.
>I too wrote a Forth-like interpreter for Smalltalk in VisualWorks+ENVY
>about a month or so ago to try out the idea (it only took a few hours,
>but it leaves out key Forth features like BUILD>DOES>). I'll see if I
(Do you share the code? VW would be fine.)
Btw, the Forth, I found (at ftp.cygnus.com, I think) was written by someone
mentioned in the article "A History of Forth" (from HOPL II) as senior Forth
consultant. So his Forth programming style is probably very much better...
>The result of doing this is I realized: I'd much rather program in
>Smalltalk than Forth. The major point to doing Forth is speed (and
>possibly simplicity of maintainence for a VM or use for intermediate
>code), which requires a complete Forth implementation with its own stack
>running its own interpreter.
But a complete Forth system can be amaizingly small...
>John Maloney has suggested:
>> One approach might be to use Forth as an intermediate language
>> generated via translation from a subset of Smalltalk,
>> much as C is generated now.
That could be one direction. I think, there're no theoretical problems with
using Forth words instead of the usual bytecode. Method lookup and most
primitives are also easy (from the complexity view, not from the working
view) to implement. However, Smalltalk needs an efficient memory system, so
one has to implement an object heap with garbage collection on top of
Forth's static memory system.
My Forth book says that I could allocate 5 MB memory with
0 VARIABLE HEAP 5 K K ALLOT
which than can be addressed as HEAP. The simplest (but also most primitive
and not very efficient) GC seems to be a mark&compact system, which needs
one initialized TOH pointer.
HEAP VARIABLE TOH
HERE CONSTANT EOH
Next we need words, which can allocate a number of cells or bytes.
: ALLOCCELLS ( size -- addr ) 2+ 4 * ALLOCOBJ ;
: ALLOCBYTES ( size -- addr ) 11 + -4 AND ALLOCOBJ ;
: ALLOCOBJ ( size --- addr )
DUP EOH TOH - >
IF GARBAGECOLLECT DUP EOH TOH - > IF ABORT ... THEN THEN
TOH SWAP TOH +! ;
The garbage collection is called if no heap space is left. Beginning from a
list of known roots into the heap it traverses the heap, marking all
reachable (alive) objects (MARK word). Then it starts at the beginning of
the heap, copying all alive objects down, compacting all unused space. It
must also change all pointers to refer to the new address now. Without
looking it up now, I don't remember the right algorithm here, but a linked
list of references can be built while marking. (COMPACT word) After this,
the TOH points to the first free cell.
>He said this would let you code primitives in Smalltalk as now, and have
>a choice of genrating Forth right now for a speedup, or later compiling
>to C for maximum performance.
After reading some papers about Forth's technology of threaded code, I doubt
that compiling to C will give you a better performance. There's an
interesting paper about this topic at the University of Vienna (Austria). It
says that threaded code has an advantage against normal interpreted bytecode
of 2:1 and is still faster than anythink that you can generate with a
standard C compiler without assembler.
>A fairly complete description of all Forth threading techniques and
>their relative speeds can be found at:
>
>http://www.complang.tuwien.ac.at/forth/threaded-code.html
Oh well, I should have read along. That's the paper I was refering to.
>Of course, simple primitives which are composed of simple words that are
>basically inlined assembler would run at near C speed (ignoring the C
>compilers optimizing ability, which might be significant for high end
>CPUs). Again, it depends on exactly what you are doing. If FPU calls
But which of course can be done with Forth too. Supposing a Forth system
could inline its primitives assembler code instead of threading it, doing a
peephole optimization, the results should be nearly the same.
However, I would compare the speed relative to the existing VM, and not to
an hypotetically optimal C program. And here, (as you've alread written) is
Forth significantly faster than the current approach.
However, Forth code is probably also larger. My VisualWorks system (I
haven't my Squeak handy, but the bytecodes should be similar) has 2389
classes with 27535 CompiledMethods totaling 544697 bytes (19 bytes per
method on the average). The worst case would be a factor of 4 growth,
because each bytecode is represented as one threaded instruction. However,
about 1/3 of all instructions are 2 byte instructions (94171). So the netto
factor is probably about x3. But there are probably some bytecode sequences
one could combine and a factor of x2 could be possible.
>Clearly, the overhead rate would be higher for byte manipulation,
>although again it depends on the task, and on whether the lowest level
>words were highly optimized or not. Many Forths allows one to easily
>inline assembler, so for example a BitBlit primitive might be composed
>of several Forth words, only a couple of which might be hand coded
>assembler of a few operations each. If these hand coded primitives did
>the bulk of the inner loop work, then the overhead again might not be
>that bad. (Note that an inlined assembler option generally isn't
>available in portable Forth in C).
Instead of the Smalltalk->C translator, which builds the VM, we should have
an Smalltalk->Forth translator. You could (and probably must :-) then
hand-optimize the result.
>The key thing to remember is that Forth developers are very concerned
>about these speed issues for threaded code, and have experience with
>them on a wide range of CPU architectures, and it would be nice to
>leverage all their work (or at least, their knowledge).
Absolutely right. I got the same impression after reading some papers about
the work done here. For example, as the inner loop of Forth needs its stack
pointer and the instruction pointer, these values can be kept in dedicated
registers which speeds up function calls. The use of the stack can be
optimized by holding the stacktop in a dedicated register and so one.
bye
--
Stefan Matthias Aust // Too much truth is unhealthy...
http://www.kiel.netsurf.de/users/s/sma/
Date: 97 Feb 04 10:14:10 am
From: Stefan Matthias Aust <sma@kiel.netsurf.de>
To: squeak@create.ucsb.edu
Subject: Merging 4TH & ST for Speed
>Thanks for your analysis of the different speedup alternatives available
>for Squeak. I too want a fast Squeak, and know that Squeak-Forth
>probably won't ever be as fast as dynamic native compilation of
>Smalltalk (especially with types). I'm just trying to find a solution
Ahhh, no types for optimiziation, please! The research in Self and Cecil has
shown that it can be done without type annotations, simply by using
dynamically allocated type informations and constant recompiled of more and
more optimized versions.
>to speedup Squeak that fits in my (or our) limited spare time, which is
>our greatest constraint, as you pointed out.
The step from interpreted bytecode directly to native code generation is
probably to big, but with smaller steps, using Forth-like technics one can
probably achive a good speedup for less work.
>* it is written (mostly) in itself (like Smalltalk) and so it can be
>easily bootstrapped and can be fairly portable
Well, does current Forths have already overcome the 7-bit ASCII gap,
allowing me to use all letters of my native language, not only A-Z? (Not
talking about unicode to include all other contries with need even more
special characters besides the ISO 8859 standard)
>* it can easily (i.e. a weeks work or so for someone who knows how to do
>it) be made to run really fast (i.e. close to compiled C speed) on any
>hardware (using a few key words written in assembler)
Is there any literature, which describes this bootstrap process?
>* a Smalltalk VM written in Forth might be a very malleable thing for
>testing OO notions and adding on other language support (like LISP,
>PROLOG, Python, BASIC, etc.), like Ian's suggestion for a general object
>engine
Seems to be a strong argument and goes in the same direction as Ian wanted
to go. And it's probably faster and better to test and to debug than pure C
(once you have learn to read Forth :-)
>* it has an interested and experienced technical community of thousands
>of engineers (many who do Forth partially as a hobby for things like
>Robotics). This is the same reason I prefer using Smalltalk over a
>homebrew language, since it has more people interested in it.
>How many people have an intimite knowledge of any particular Smalltalk
>byte code set? If people are going to study the VM to change it, they
As me a number :-) 71? That's "push false"
>* it could possibly replace Java or the Java VM with the right words
That's perhaps a bit too intuiastic... (1000 flies can't go wrong...)
>* one might be able to easily extend the Squeak debugger so it
>transparently debugged from Smalltalk into a Forth primitive.
That would be cool...
>Also, Forth does have other disadvantages mentioned here and elsewhere:
>* Byte codes are more compact than Forth. One could hope this could be
>worked around - perhaps with an intermediate table and a way to have
>byte code strings contain variable length address references (one or two
>bytes indexes as needed into a jump table to Forth code)
Typical space/time trade-off. That shouldn't be a great problem nowadays
(perhaps with the Newton as exception).
bye
--
Stefan Matthias Aust // Too much truth is unhealthy...
http://www.kiel.netsurf.de/users/s/sma/
Date: 97 Feb 04 10:46:27 am
From: Ian Piumarta <piumarta@prof.inria.fr>
To: sma@kiel.netsurf.de
Cc: squeak@create.ucsb.edu
Subject: Re: Merging Forth and Smalltalk
Hmm.
> DUP EOH TOH - >
> IF GARBAGECOLLECT DUP EOH TOH - > IF ABORT ... THEN THEN
> TOH SWAP TOH +! ;
This is some sort of TECO error message, right?
;-)
Ian
PS: I'm not really being cynical -- I spent a couple of years implementing
Forths on various machines in my pre-university days. I had to
invent my own dialects, mainly becuase I couldn't find ANY
documentation on the language -- and to this day I *still* haven't
figured out what COMPILES:DOES> [or was it CREATES:DOES> ?] is
supposed to do, based on the scanty example programs that I saw
way back then...
PPS: Did you know that Sun machines use Forth as the PROM monitor language
and bootstrap loader? When you type "probe-scsi" you're actually
running a Forth function. You can even type Forth programs at
that "ok " prompt!!!
PPPS: I seem to be rambling, way off-topic. Sorry. ;)
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes a Objets Repartis -----------------------
Date: 97 Feb 04 12:17:39 pm
From: Jecel Assumpcao Jr <jecel@lsi.usp.br>
To: Squeak@create.ucsb.edu
Subject: Quicktalk (was: Merging Forth and Smalltalk)
Forth is one of my favorite languages, but it would be
far better to use a subset of Smalltalk for creating
primitives in Squeak than to mix the two languages.
I was reading about Quicktalk yesterday (OOPSLA'86) and
it was precisely such a subset. It was disappointing for
me because I was hoping for something to access functionality
not available in Smalltalk but Quicktalk is strictly for
speeding up things.
I found it neat that the code for the primitive was
embedded in the source of method that used it, something
like this.
+ arg
"adds arg to self"
{
SmallInteger checkClass: arg.
^ self + arg
}
^ arg + self
The details were different, but that is the general idea.
Inside the braces, you could only use a very limited set
of message selectors with fixed definitions (so the "+"
inside the braces is very different from the #+ in the
last line.
I found the idea of type checking through explicit code
an interesting alternative to declarations in this
context. If arg is not a SmallInteger, the primitive
part will fail transparently and the Smalltalk code
will run. That is standard Smalltalk semantics for
primitives, but I would prefer to use an explicit
exception mechanism so I could check for wrong types
*or* overflow, for example.
The authors of the paper mentioned that they would prefer
to be able to call the primitives as if it were a
normal method (like in Self) and I think that Dan's
idea would allow this. Another option would be to allow
expressions in braces to be freely mixed with normal
Smalltalk code (as is done in Smalltalk/X, where
expressions in braces are written in C). They would
then be able to be treated as normal Smalltalk expressions
too (since they are a strict subset if all of their
special selectors are also implemented as normal Smalltalk
methods) and tested, but then they could be treated
very differently when translating to C or to some
runtime threaded code.
In fact, if we used special comments to delimit such
primitive expressions (like "primitive-on" and
"primitive-off") then the exact same code could run
on other Smalltalks as well.
-- Jecel
Date: 97 Feb 04 12:35:20 pm
From: Les Tyrrell <tyrrell@avalanche.ncsa.uiuc.edu>
To: squeak@create.ucsb.edu
Subject: RE: Quicktalk (was: Merging Forth and Smalltalk)
If one is willing to accept a "slow" prototyping environment
( which, since we are talking about Smalltalk, indicates that
we are ) but still would like to have fast runtimes, it appears
that there are already a number of options. As food for thought,
these are ( with vague references for which I apoligize in advance...
I do have them, but I'm still sorting through my papers, and the
machine that has the CD-ROM with the OOPSLA proceedings is dead
at the moment... grrr. )
1) Producer
Already in existence, within the UIUC archive.
Generates Objective-C code from Smalltalk.
Described in OOPSLA proceedings.
( Brad Cox with Kurt J. Schmucker )
2) QuickTalk
A Smalltalk dialect for creating Smalltalk primitives.
Availability unknown.
Described in OOPSLA proceedings.
( Mark B. Ballard, David Maier, Allen Wirfs-Brock )
3) Hurricane
Along the lines of QuickTalk, but perhaps
more flexible. "An optimimizing compiler for Smalltalk".
Described in same OOPSLA as QuickTalk.
( Robert G. Atkinson )
4) Squeak's own C-code generator
Relationship to Producer, Quicktalk or Hurricane unkown.
( Who wrote this? )
5) There have been numerous efforst aimed at Typing
Smalltalk- again, Described in OOPSLA and elsewhere.
The general gist appears to be that in order to achieve
significant gains in performance over regular Smalltalk,
some form of typing is required in order to enable more
global optimisation, rather than being restricted to only
optimizing within a given method. Ralph Johnson has
looked at this a few times-
"Type Checking Smalltalk" ( OOPSLA 86? )
Ralph Johnson
6) Modular Smalltalk
Originally described in OOPSLA 88 ( I remember that one, anyway ).
( Allen Wirfs-Brock and Brian Wilkerson )
"Recently" also described in a Tektronix technical report,
"Modular Smalltalk Language Proposal, Technical Report
CRL-89-03" of 1989, as well as in a more recent thesis,
"A First Implementation of Modular Smalltalk" by Wade
Holst at the University of Alberta. There is also a technical
report by the same name, Technical Report TR 93-07,
from 1993. This is of interest, since in addition to an
apparent implementation of Modular Smalltalk, there
is discussion of what may be a Meta-Object Protocol
style implementation of this system, and a flexible
macro-based C code generator that apparently can
easily support assembly code generation as well, and
is not restricted to working only with Smalltalk. These
are first impressions, I just got these yesterday.
http://web.cs.ualberta.ca/~wade/Personal/Papers/thesis.modular_smalltalk.ps.gz
ftp://ftp.cs.ualberta.ca/pub/TechReports/1993/TR93-07/TR93-07.ps.Z
Food for thought- there are a number of ideas in these papers, and this
is just scratching the surface. I think there is considerable room for
exploration on all these issues, and Squeak is a good environment for
doing this. Smalltalk is by no means a dead-end environment!
So that's a start on the issues of performance... Now I might add that
it would be good to start thinking in terms of massively distributed,
parrallel, concurrent, etc. systems built using Smalltalk, by very
large teams of programmers, and what that entails. Again, there is
already a sizeable body of literature to get the wheels turning...
and I'm NOT talking Java.
Les
tyrrell@avalanche.ncsa.uiuc.edu
PS: Sorry for incomplete references... Real Soon Now I'll have this stuff
sorted out.
Date: 97 Feb 04 10:47:10 pm
From: Dan Ingalls <DanI@wdi.disney.com>
To: Squeak@create.ucsb.edu
Subject: Bug Fix: Space estimate in newDepth:
In version 1.18 a check is made to see if you are about to change to a=
display depth that would run you out of memory in a bad way. It was overly=
pessimistic, tallying the area of all windows, not just those that require=
full-depth cached bitmaps. The following code should do a more reasonable =
job.
!DisplayScreen methodsFor: 'private'!
newDepthNoRestore: pixelSize
"Change depths. Check if there is enough space. 2/4/97, di"
| area need |
pixelSize =3D depth ifTrue: [^ self "no change"].
pixelSize < depth ifFalse:
["Make sure there is enough space"
area _ Display boundingBox area. "pixels"
ScheduledControllers scheduledWindowControllers do:
[:aController | aController view cacheBitsAsTwoTone ifFalse:
[area _ area + aController view windowBits boundingBox area]].
need _ (area * pixelSize // 8) - (area * depth // 8) "new bytes needed"
+ 80000. "lowSpaceThreshold (should be shared)"
(Smalltalk garbageCollectMost <=3D need
and: [Smalltalk garbageCollect <=3D need])
ifTrue: [self halt: 'Insufficient free space']].
self depth: pixelSize. =20
self setExtent: self extent.
ScheduledControllers updateGray.
DisplayScreen startUp! !
Date: 97 Feb 05 9:02:26 pm
From: Les Tyrrell <tyrrell@avalanche.ncsa.uiuc.edu>
To: Squeak@create.ucsb.edu
Subject: TinyTalk
I've been sorting through my papers, and came across one about TinyTalk.
This was written by Kim McCall and Larry Tesler, and I beleive it was
referenced by an article in the August 81 Byte. The title of this
paper is "TinyTalk, a Subset of Smalltalk-76 for 64KB Microcomputers",
and I believe it appeared in an ACM journal primarily concerned with
personal or micro computers ( actually, more like a newsletter )
in 1980.
I've never seen any other articles or references to information about
this system, and was curious if there might exist any further information
beyond this one article, which is only two pages and very sketchy.
Thanks!
Les
Date: 97 Feb 06 6:35:34 am
From: Ian Piumarta <piumarta@prof.inria.fr>
To: jecel@lsi.usp.br
Cc: Squeak@create.ucsb.edu
In-Reply-To: <32F78F9F.7E92523B@lsi.usp.br> (message from Jecel Assumpcao Jr
on Tue, 04 Feb 1997 17:35:59 -0200)
Subject: Re: Quicktalk (was: Merging Forth and Smalltalk)
> + arg
> "adds arg to self"
> {
> SmallInteger checkClass: arg.
> ^ self + arg
> }
> ^ arg + self
I like this approach a lot. (Didn't Typed Smalltalk also allow you to
specify primitives using the RTL language that it used as an intermediate
representation in the Smalltalk compiler?)
The only problem with it is that some primitives are used in many different
places. Ignoring the primitives used only once:
freq primitive(s)
---- ------------
2 110, 121, 141, 14, 15, 16, 17, 65, 71, 7, 8, 90, 96
3 61, 70, 75
4 81, 83, 91
5 105, 60, 62
I know this isn't really a problem, but I thought I'd point it out...
Another approach, which appeals to me very much (as a part-time compiler
hacker ;-), is to have a dialect of "sys-Smalltalk" (like the sys-Lisp that
Lispers use to implement their primitives) in which you write your primitives
(just like in Jecel's example). The Smalltalk compiler parses this into the
very simple (architecture independent) "almost-AST"s used by GCC as the input
to its RTL generation phase. You link the GCC back-end for your particular
platform into the Squeak VM (or make it a DLL, or whatever) and you can
immediately generate assembler sources for the primitives -- which would run
at least as fast as fully-optimised C. (Maybe faster, in some situations,
since your primitives would not be restricted by C's semantics any more.)
This is the same technique that the FSF use to provide all those different
language front ends, feeding into GCC's single back end. (And which several
other independent groups have used in the same way to make compilers for
various other languages.)
I imagine that Squeak's current Smalltalk->C translator could be modified
very easily (mainly by ripping out unnecessary stuff) to generate the
required ASTs.
(There's an interesting discussion about this in the comp.compilers archive.)
Ian
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes a Objets Repartis -----------------------
Date: 97 Feb 06 7:32:12 am
From: Hans-Martin Mosner <hmm@heeg.de>
To: Ian Piumarta <piumarta@prof.inria.fr>
Cc: jecel@lsi.usp.br, Squeak@create.ucsb.edu
Subject: Re: Quicktalk (was: Merging Forth and Smalltalk)
------------134F7EFCF650
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=us-ascii
Hi,
Ian Piumarta wrote:
>
> > + arg
> > "adds arg to self"
> > {
> > SmallInteger checkClass: arg.
> > ^ self + arg
> > }
> > ^ arg + self
>
> I like this approach a lot. (Didn't Typed Smalltalk also allow you to
> specify primitives using the RTL language that it used as an
intermediate
> representation in the Smalltalk compiler?)
>
Just for trying out what is possible, I have implemented a hack that
allows me
to compile machine language instructions and call it with a primitive.
I used Dan's syntax of:
method: argument
<primitive>
^argument + self
with the following features:
1. <primitive> without a primitive number is compiled into <primitive:
255>, and the
first literal of the compiled method is set to an empty byte array that
is later used
to contain the compiled code.
2. The parser inserts an invisible "self compilePrimitive" statement as
the first
statement of the method.
3. The method gets called.
4. If the primitive 255 encounters a non-empty byte array as the first
literal of its
method, it calls the code with a number of arguments: pointer to
receiver¶meters,
numArgs, pointer to literals of method. The compiled code can use this
information
to do the right thing. It should either return a good oop (then we're
done), or the
integer 0 to signal a primitive failure.
4.a. If the primitive 255 encounters an empty bytecode array, it assumes
that the code
has not yet been generated, and fails immediately.
5. #compilePrimitive analyzes the bytecodes of the method and generates
machine code for it.
This machine code is installed as the first literal of the method.
6. Then the normal Smalltalk code takes over for the first invocation of
this primitive.
I have all this working for Windows NT, except the simple step 5 which
is left as an exercise
for the reader :-)
My idea was to have a architecture-independent system that translates
the bytecodes into
a kind of dataflow graph, and then the architecture-dependent part
generates real code for it.
This is certainly not easy to do right...
Now Ian wrote on:
>
> Another approach, which appeals to me very much (as a part-time
compiler
> hacker ;-), is to have a dialect of "sys-Smalltalk" (like the sys-Lisp
that
> Lispers use to implement their primitives) in which you write your
primitives
> (just like in Jecel's example). The Smalltalk compiler parses this
into the
> very simple (architecture independent) "almost-AST"s used by GCC as
the input
> to its RTL generation phase. You link the GCC back-end for your
particular
> platform into the Squeak VM (or make it a DLL, or whatever) and you
can
> immediately generate assembler sources for the primitives -- which
would run
> at least as fast as fully-optimised C. (Maybe faster, in some
situations,
> since your primitives would not be restricted by C's semantics any
more.)
>
Looks like this would be an option to use existing work that does mostly
what we
want: generate good assembly language from an architecture-independent
intermediate format. Although I would rather like to have full control
over the
translation process, I could live with an external library for which
source is available.
If anybody is interested in my code, look at
http://www.heeg.de/~hmm/squeak/PrimitiveCompiler.cs
and
http://www.heeg.de/~hmm/squeak/primcall.c
to see how it's done.
Hans-Martin
------------134F7EFCF650
Content-Transfer-Encoding: 7bit
Content-Type: text/html; charset=us-ascii
<HTML><BODY>
<DT>Hi,</DT>
<DT>Ian Piumarta wrote:<BR>
> <BR>
> > + arg<BR>
> > "adds arg to self"<BR>
> > {<BR>
> > SmallInteger checkClass: arg.<BR>
> > ^ self + arg<BR>
> > }<BR>
> > ^ arg + self<BR>
> <BR>
> I like this approach a lot. (Didn't Typed Smalltalk also allow
you to<BR>
> specify primitives using the RTL language that it used as an intermediate<BR>
> representation in the Smalltalk compiler?)<BR>
> <BR>
Just for trying out what is possible, I have implemented a hack that allows
me</DT>
<DT>to compile machine language instructions and call it with a primitive.</DT>
<DT>I used Dan's syntax of:</DT>
<DT> method: argument</DT>
<DT> <primitive></DT>
<DT> ^argument + self</DT>
<DT>with the following features:</DT>
<DT>1. <primitive> without a primitive number is compiled into <primitive:
255>, and the</DT>
<DT>first literal of the compiled method is set to an empty byte array
that is later used</DT>
<DT>to contain the compiled code.</DT>
<DT>2. The parser inserts an invisible "self compilePrimitive"
statement as the first</DT>
<DT>statement of the method.</DT>
<DT>3. The method gets called.</DT>
<DT>4. If the primitive 255 encounters a non-empty byte array as the first
literal of its</DT>
<DT>method, it calls the code with a number of arguments: pointer to receiver¶meters,</DT>
<DT>numArgs, pointer to literals of method. The compiled code can use this
information</DT>
<DT>to do the right thing. It should either return a good oop (then we're
done), or the</DT>
<DT>integer 0 to signal a primitive failure.</DT>
<DT>4.a. If the primitive 255 encounters an empty bytecode array, it assumes
that the code</DT>
<DT>has not yet been generated, and fails immediately.</DT>
<DT>5. #compilePrimitive analyzes the bytecodes of the method and generates
machine code for it.</DT>
<DT>This machine code is installed as the first literal of the method.</DT>
<DT>6. Then the normal Smalltalk code takes over for the first invocation
of this primitive.</DT>
<DT> </DT>
<DT>I have all this working for Windows NT, except the simple step 5 which
is left as an exercise</DT>
<DT>for the reader :-)</DT>
<DT>My idea was to have a architecture-independent system that translates
the bytecodes into</DT>
<DT>a kind of dataflow graph, and then the architecture-dependent part
generates real code for it.</DT>
<DT>This is certainly not easy to do right...</DT>
<DT> </DT>
<DT>Now Ian wrote on:<BR>
> <BR>
> Another approach, which appeals to me very much (as a part-time compiler<BR>
> hacker ;-), is to have a dialect of "sys-Smalltalk" (like
the sys-Lisp that<BR>
> Lispers use to implement their primitives) in which you write your
primitives<BR>
> (just like in Jecel's example). The Smalltalk compiler parses
this into the<BR>
> very simple (architecture independent) "almost-AST"s used
by GCC as the input<BR>
> to its RTL generation phase. You link the GCC back-end for your
particular<BR>
> platform into the Squeak VM (or make it a DLL, or whatever) and you
can<BR>
> immediately generate assembler sources for the primitives -- which
would run<BR>
> at least as fast as fully-optimised C. (Maybe faster, in some
situations,<BR>
> since your primitives would not be restricted by C's semantics any
more.)<BR>
> <BR>
<BR></DT>
<DT>Looks like this would be an option to use existing work that does mostly
what we</DT>
<DT>want: generate good assembly language from an architecture-independent</DT>
<DT>intermediate format. Although I would rather like to have full control
over the</DT>
<DT>translation process, I could live with an external library for which
source is available.</DT>
<DT> </DT>
<DT>If anybody is interested in my code, look at</DT>
<DT> http://www.heeg.de/~hmm/squeak/PrimitiveCompiler.cs</DT>
<DT>and</DT>
<DT> http://www.heeg.de/~hmm/squeak/primcall.c</DT>
<DT>to see how it's done.</DT>
<DT> </DT>
<DT>Hans-Martin</DT>
</BODY>
</HTML>
------------134F7EFCF650--
Date: 97 Feb 06 9:28:38 am
From: Dan Ingalls <DanI@wdi.disney.com>
To: Squeak@create.ucsb.edu
In-Reply-To: <32F78F9F.7E92523B@lsi.usp.br>
Subject: Re: Quicktalk (was: Merging Forth and Smalltalk)
>+ arg
> "adds arg to self"
> {
> SmallInteger checkClass: arg.
> ^ self + arg
> }
> ^ arg + self
>
>The details were different, but that is the general idea.
>Inside the braces, you could only use a very limited set
>of message selectors with fixed definitions (so the "+"
>inside the braces is very different from the #+ in the
>last line.
If at all possible, I want to stick with a SINGLE VERSION of the code. The=
primitive flag means that the code is subset code. The assertions (I=
prefer 'arg mustBeA: SmallInteger') inform the compiler, and also let the=
primitive code fail if they are not met. Then the same code runs in ST and=
you see where your error is. There may be some problem with this but, if=
not, then it makes life a lot nicer because once the thing has run in ST,=
you have fair assurance that it will run as a primitive. This is the case=
now with John's approach to the music primitives.
Just so you can meditate on it, here below is the synthesis primitive in=
FMSound. I'd like to clean up the declarations, but the EXACT SAME CODE=
runs (and was debugged) in ST, and compiles (via C) to native code. When=
we timed it, the compilation achieved a 40x speed-up!
----------------------------------------------------------------
mixSampleCount: n into: aSoundBuffer startingAt: startIndex pan: pan
"A simple implementation of Chowning's frequency-modulation synthesis=
technique. The center frequency is varied as the sound plays by changing=
the increment by which to step through the wave table."
"FMSound majorScale play"
"(FMSound pitch: 440.0 dur: 1.0 loudness: 200) play"
| lastIndex mySample sample channelIndex |
<primitive>
self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
self var: #waveTable declareC: 'short int *waveTable'.
lastIndex _ (startIndex + n) - 1.
startIndex to: lastIndex do: [ :i |
mySample _ (amplitude * (waveTable at: index)) // 1000.
pan > 0 ifTrue: [
channelIndex _ 2 * i.
sample _ (aSoundBuffer at: channelIndex) + ((mySample * pan) // 1000).
sample > 32767 ifTrue: [ sample _ 32767 ]. "clipping!"
sample < -32767 ifTrue: [ sample _ -32767 ]. "clipping!"
aSoundBuffer at: channelIndex put: sample.
].
pan < 1000 ifTrue: [
channelIndex _ (2 * i) - 1.
sample _ (aSoundBuffer at: channelIndex) + ((mySample * (1000 - pan)) // =
1000).
sample > 32767 ifTrue: [ sample _ 32767 ]. "clipping!"
sample < -32767 ifTrue: [ sample _ -32767 ]. "clipping!"
aSoundBuffer at: channelIndex put: sample.
].
index _ index + increment + ((modulation * (waveTable at: offsetIndex)) //=
1000000).
index > waveTableSize ifTrue: [
index _ index - waveTableSize.
].
index < 1 ifTrue: [
index _ index + waveTableSize.
].
offsetIndex _ offsetIndex + offsetIncrement.
offsetIndex > waveTableSize ifTrue: [
offsetIndex _ offsetIndex - waveTableSize.
].
].
count _ count - n.
Date: 97 Feb 06 1:34:46 pm
From: Ian Piumarta <piumarta@prof.inria.fr>
To: squeak@create.ucsb.edu
Subject: interpreter hack for approx. 13% speedup
Dear Unix Squeakers,
If you can recompile your InterpTestInline.c then there's a quick hack
that you can do which will yield the following performance increase
(timed on my IPX):
old 1.18 hacked 1.18 increase
-------- ----------- --------
26 benchFib 46000 50000 8.7%
10 benchmark 925000 1084000 17.2%
It relies on eliminating a redundant range check and jump chain
performed each time round the bytecode dispatch loop. You will need
gcc, since it relies on gcc's first-class labels. Here's what you do.
In the function interpret(), make the following modifications:
1) just after the declaration of the last temporary (t17) define an
array of 256 local label addresses:
void *labels[256]= {
&&_0, &&_1, &&_2, &&_3, &&_4, &&_5, &&_6, &&_7,
&&_8, &&_9, &&_10, &&_11, &&_12, &&_13, &&_14, &&_15,
[...]
&&_240, &&_241, &&_242, &&_243, &&_244, &&_245, &&_246, &&_247,
&&_248, &&_249, &&_250, &&_251, &&_252, &&_253, &&_254, &&_255 };
(hackers wearing hats with little propellers on top might like to
write a teeny bit of Emacs lisp to generate these 256 initialisers ;-)
2) immediately after the above definition, define a macro "CASE(N)" which
declares a case label N and a local label _N:
#define CASE(N) case N: _##N:
3) immediately after the CASE definition, redefine "break" so that it
jumps to the appropriate local label (instead of exiting the switch
and iterating around the dispatch loop):
#define break \
currentBytecode = byteAt(++localIP); \
goto *labels[currentBytecode]
4) inside the body of interpret(), replace all 256 occurences of
case XYZ:
with
CASE(XYZ)
(NOTE the lack of trailing colon!)
5) immediately after the end of the interpret() function, just before
the start of the isBytes() function, #undef the two previous
definitions:
#undef break
#undef CASE
6) recompile InterpTestInline.c and relink your VM.
7) consider the "seal broken" and your "warranty invalidated"! ;^)
Ian
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes d'Objets Repartis -----------------------
Date: 97 Feb 06 2:03:53 pm
From: Randal Schwartz <merlyn@stonehenge.com>
To: Ian Piumarta <piumarta@prof.inria.fr>
Cc: squeak@create.ucsb.edu
In-Reply-To: Ian Piumarta's message of Thu, 6 Feb 1997 22:44:19 +0100
Subject: Re: interpreter hack for approx. 13% speedup
>>>>> "Ian" == Ian Piumarta <piumarta@prof.inria.fr> writes:
Ian> 1) just after the declaration of the last temporary (t17) define an
Ian> array of 256 local label addresses:
Ian> void *labels[256]= {
Ian> &&_0, &&_1, &&_2, &&_3, &&_4, &&_5, &&_6, &&_7,
Ian> &&_8, &&_9, &&_10, &&_11, &&_12, &&_13, &&_14, &&_15,
Ian> [...]
Ian> &&_240, &&_241, &&_242, &&_243, &&_244, &&_245, &&_246, &&_247,
Ian> &&_248, &&_249, &&_250, &&_251, &&_252, &&_253, &&_254, &&_255 };
Ian> (hackers wearing hats with little propellers on top might like to
Ian> write a teeny bit of Emacs lisp to generate these 256 initialisers ;-)
Naaah:
$ perl >Out
print
"void *labels[256] = {\n",
(map {(" ", (map "&&_$_, ", (8*$_)..(8*$_+7)), "\n")} 0..31),
"}\n";
^D
$
--
Name: Randal L. Schwartz / Stonehenge Consulting Services (503)777-0095
Keywords: Perl training, UNIX[tm] consulting, video production, skiing, flying
Email: <merlyn@stonehenge.com> Snail: (Call) PGP-Key: (finger merlyn@ora.com)
Web: <A HREF="http://www.stonehenge.com/merlyn/">My Home Page!</A>
Quote: "I'm telling you, if I could have five lines in my .sig, I would!" -- me
Date: 97 Feb 06 3:19:25 pm
From: Dan Ingalls <DanI@wdi.disney.com>
To: Randal Schwartz <merlyn@stonehenge.com>
Cc: Squeak@create.ucsb.edu
In-Reply-To: <8chgjpinww.fsf@gadget.cscaper.com>
Subject: Re: interpreter hack for approx. 13% speedup
>Naaah:
>
> $ perl >Out
> print
> "void *labels[256] = {\n",
> (map {(" ", (map "&&_$_, ", (8*$_)..(8*$_+7)), "\n")} 0..31),
> "}\n";
> ^D
> $
>
Squeak is not too far off with...
((0 to: 31) inject: 'void *labels[256] = {' into:
[:str :i8 | str , Character cr asString ,
((0 to: 7) inject: '' into: [:s :i | s , ' &&_' , (i8*8+i) printString , ','])]) , '}
'
... although it leaves a comma to be removed.
- Dan
Date: 97 Feb 06 4:15:31 pm
From: Maloney <johnm@wdi.disney.com>
To: Ian Piumarta <piumarta@prof.inria.fr>
Cc: Squeak@create.ucsb.edu
In-Reply-To: <199702061444.PAA21989@prof.inria.fr>
Subject: Re: Quicktalk (was: Merging Forth and Smalltalk)
>I imagine that Squeak's current Smalltalk->C translator could be modified
>very easily (mainly by ripping out unnecessary stuff) to generate the
>required ASTs.
We've talked about doing this. The main thing that stops us is
just the mechanics of calling the C compiler at runtime in a portable way.
If we linked in gcc, we might be subject to the gnu license, which is a bit
too restrictive for us.
If anyone can figure out how to solve the problem of calling the C
compiler and linking in the resulting object code, I'd be happy to
help them get the ST-to-C translator to spit out the right
intermediate language!
-- John
Date: 97 Feb 06 4:16:04 pm
From: Maloney <johnm@wdi.disney.com>
To: Squeak@create.ucsb.edu
In-Reply-To: <v03007802af1fbd73322a@[206.16.10.79]>
Subject: Re: Quicktalk (was: Merging Forth and Smalltalk)
Gentle Squeakers:
Re:
> Just so you can meditate on it, here below is the synthesis primitive in FMSound.
> I'd like to clean up the declarations, but the EXACT SAME CODE runs (and was
> debugged) in ST, and compiles (via C) to native code. When we timed it, the
> compilation achieved a 40x speed-up!
Here is the code generated from the Smalltalk code Dan sent out (which is
repeated at the end of this message). Note that the translator uses the
declarations to tell it that aSoundBuffer and waveTable are arrays. The
"fetchxxx" and "storexxx" message fetch arguments and instance variables
into C variables and store back any instance variables that are modified
by the method. Anything not declared otherwise is assumed to be an
integer.
Cheers!
-- John
----------------------------------------------------------------
int primFMSoundmixSampleCountintostartingAtpan(void) {
int rcvr;
int n;
short int *aSoundBuffer;
int startIndex;
int pan;
int sample;
int i;
int lastIndex;
int mySample;
int channelIndex;
short int *waveTable;
int waveTableSize;
int count;
int amplitude;
int increment;
int index;
int modulation;
int offsetIncrement;
int offsetIndex;
rcvr = longAt(stackPointer - (4 * 4));
n = checkedIntegerValueOf(longAt(stackPointer - (3 * 4)));
aSoundBuffer = arrayValueOf(longAt(stackPointer - (2 * 4)));
startIndex = checkedIntegerValueOf(longAt(stackPointer - (1 * 4)));
pan = checkedIntegerValueOf(longAt(stackPointer - (0 * 4)));
waveTable = fetchArrayofObject(1, rcvr);
waveTableSize = fetchIntegerofObject(2, rcvr);
count = fetchIntegerofObject(4, rcvr);
amplitude = fetchIntegerofObject(6, rcvr);
increment = fetchIntegerofObject(8, rcvr);
index = fetchIntegerofObject(9, rcvr);
modulation = fetchIntegerofObject(11, rcvr);
offsetIncrement = fetchIntegerofObject(13, rcvr);
offsetIndex = fetchIntegerofObject(14, rcvr);
if (!(successFlag)) {
return null;
}
lastIndex = (startIndex + n) - 1;
for (i = startIndex; i <= lastIndex; i += 1) {
mySample = (amplitude * (waveTable[index - 1])) / 1000;
if (pan > 0) {
channelIndex = 2 * i;
sample = (aSoundBuffer[channelIndex - 1]) + ((mySample * pan) / 1000);
if (sample > 32767) {
sample = 32767;
}
if (sample < -32767) {
sample = -32767;
}
aSoundBuffer[channelIndex - 1] = sample;
}
if (pan < 1000) {
channelIndex = (2 * i) - 1;
sample = (aSoundBuffer[channelIndex - 1]) + ((mySample * (1000 - pan)) / 1000);
if (sample > 32767) {
sample = 32767;
}
if (sample < -32767) {
sample = -32767;
}
aSoundBuffer[channelIndex - 1] = sample;
}
index = (index + increment) + ((modulation * (waveTable[offsetIndex - 1])) / 1000000);
if (index > waveTableSize) {
index = index - waveTableSize;
}
if (index < 1) {
index = index + waveTableSize;
}
offsetIndex = offsetIndex + offsetIncrement;
if (offsetIndex > waveTableSize) {
offsetIndex = offsetIndex - waveTableSize;
}
}
count = count - n;
storeIntegerofObjectwithValue(4, rcvr, count);
storeIntegerofObjectwithValue(9, rcvr, index);
storeIntegerofObjectwithValue(14, rcvr, offsetIndex);
pop(4);
}
Here is the Smalltalk from which the above was generated:
>----------------------------------------------------------------
>
>mixSampleCount: n into: aSoundBuffer startingAt: startIndex pan: pan
> "A simple implementation of Chowning's frequency-modulation synthesis technique. The center frequency is varied as the sound plays by changing the increment by which to step through the wave table."
> "FMSound majorScale play"
> "(FMSound pitch: 440.0 dur: 1.0 loudness: 200) play"
>
> | lastIndex mySample sample channelIndex |
> <primitive>
> self var: #aSoundBuffer declareC: 'short int *aSoundBuffer'.
> self var: #waveTable declareC: 'short int *waveTable'.
>
> lastIndex _ (startIndex + n) - 1.
> startIndex to: lastIndex do: [ :i |
> mySample _ (amplitude * (waveTable at: index)) // 1000.
> pan > 0 ifTrue: [
> channelIndex _ 2 * i.
> sample _ (aSoundBuffer at: channelIndex) + ((mySample * pan) // 1000).
> sample > 32767 ifTrue: [ sample _ 32767 ]. "clipping!"
> sample < -32767 ifTrue: [ sample _ -32767 ]. "clipping!"
> aSoundBuffer at: channelIndex put: sample.
> ].
> pan < 1000 ifTrue: [
> channelIndex _ (2 * i) - 1.
> sample _ (aSoundBuffer at: channelIndex) + ((mySample * (1000 - pan)) // 1000).
> sample > 32767 ifTrue: [ sample _ 32767 ]. "clipping!"
> sample < -32767 ifTrue: [ sample _ -32767 ]. "clipping!"
> aSoundBuffer at: channelIndex put: sample.
> ].
>
> index _ index + increment + ((modulation * (waveTable at: offsetIndex)) // 1000000).
> index > waveTableSize ifTrue: [
> index _ index - waveTableSize.
> ].
> index < 1 ifTrue: [
> index _ index + waveTableSize.
> ].
> offsetIndex _ offsetIndex + offsetIncrement.
> offsetIndex > waveTableSize ifTrue: [
> offsetIndex _ offsetIndex - waveTableSize.
> ].
> ].
> count _ count - n.
>----------------------------------------------------------------
Date: 97 Feb 07 4:54:48 am
From: Jecel Assumpcao Jr <jecel@lsi.usp.br>
To: Squeak@create.ucsb.edu
Subject: compiling (was: Quicktalk)
Dan showed the advantages of having a single Smalltalk source
that is able to run as either a normal method or compiled
into a primitive. Ian explained that some primitives are
called from several places, so it would be better for them
to be separate methods than "manually" inlined where they
are used.
Though I tried to show some alternatives, I actually
agree with both.
One sticky problem is how to handle primitive failures
in the same way when running as either a normal method
or a compiled primitive. My personal choice would be
to use a full exception mechanism, but I think that the
solution that Self uses might come in handy:
Self primitives are called using the normal send bytecodes.
All of them can accept a block that is executed in case
the primitive fails. Here is the Self code for #+ for
SmallIntegers:
+ a = ( |
| asSmallInteger _IntAdd: a IfFail: [| :error. :name. |
('badTypeError' == error) ifTrue: [
" use double dispatching "
a addSmallInteger: asSmallInteger ] False: [
('overflowError' == error) ifTrue: [
" retry after coercing to bigInts "
asBigInteger + a asBigInteger ] False: [
primitiveFailedError: error Name: name ]]]).
So the primitive #_IntAdd:IfFail: is called as if it were
a normal Self method, with what would be the "Smalltalk
part" of the method encapsulated in a block that is only
executed when the primitive fails. This example tests the
type of error to decide what to do, but most methods
would only care that some error occured.
Inside the primitive, we would have something like:
...... ifTrue: [ ^ failBlock value: 'overflowError'
With: '_IntAdd' ]
This would allow the "primitive" to run as a normal Smalltalk
method and be called normally (and sometimes fail, with the
right effect) during testing. The hard part would be handling
blocks in a reasonable way when compiling into C or machine
language. The translator wouldn't have to handle all uses
of blocks, of course. Just the idiom
[ ^ failBlock value: .. with: ...]
Hans-Martin developed a system for runtime compilation of
primitives. I have given his "exercise for the reader" a
lot of thought in the past few months - a portable way to
generate machine code. Ian suggested linking with part
of gcc, but I feel it is better to just use some of their
ideas rather than any of their code.
I would like for there to be a TranslateCPU abstract
class with just a reduced number of methods marked as
"subclass resposibility". All the other methods would
be defined in terms of these. Now would could create
a TranslateX86 subclass and just define these few
methods to get very crude, but working machine code.
With time, we would override other methods to greatly
improve the quality of the compilation. The same
steps would be used for TranslateARM and TranslatePowerPC.
Someone might even take the time to write a subclass
of TranslateX86 called TranslatePentium to improve
scheduling. Actually, scheduling for superscalar and
VLIW machines has been the hard part of this problem.
Back to the single Smalltalk source problem. Ian
wondered what the Forth words CREATE and DOES>
(at least that is what they are called in PFE) are
for. Since I am not a Forth programmer myself (though
my "graduation project" was a Forth chip), you shouldn't
trust what I am about to write. These words are the key
to reflection in Forth.
CREATE defines a new defining word (like ":"). The code
for the new word must do thing like allocate memory
and generally patch things. You might define a defining
word picture that pops off two numbers from the stack
and allocates enough space for it (plus the numbers
themselves so the picture remembers its shape) and
associates all this with the name that follows. So
you can now write
640 480 picture myHouse
So we defined myHouse, but what happens when we *use*
myHouse in some other word? We might want it to pop
two coordinates off the stack and push the address of
the corresponding pixel (so we can read it or change
it with "@" or "!"). That is exactly what DOES> is
for - you can define this code as what is executed
every time myHouse is used:
100 100 myHouse @
So CREATE says how picture works while DOES> says how
words picture defines work. But words might have
different compile time and runtime behavior! consider
"if". At compile time, it stores the address of its
runtime behavior in the code buffer, leaves a blank
space and pushes its address on the return stack so
that "then" can pop it off and go back to patch that
space to point to the code after the "then". At runtime,
the "if" pops a number off the stack and either jumps
to the address in the space the follows it or just
skips that space.
Sorry about this long detour, but my point is that
Forth has many different behaviors for getting things
done, but we want to write a "single" piece of code
for the same job. Actually, some of the functionality
is in the compiler, some is in the bytecode interpreter
and the rest is in the methods (or primitives) we
write. One way to get some of the effect that Forth
has is to move part of the functionality from the
interpreter into an explicit reflective (or metaobject)
layer. See Jeff McAffer's CoDA for a good example:
http://web.yl.is.s.u-tokyo.ac.jp/~jeff/research/availdoc.html
One thing I want is to use partial evaluation to
extract compile time and run time behaviors from a
single Smalltalk (or Self) source, and have this also
be used to efficiently implement a reflective architecture
like Jeff's.
In short, I want compilation to merge what was written
as separate code (for modularity and understandibility)
and to separate what was written as a single method
(also for understandibility). A tall order, no doubt,
but the only route I see to really getting the best
of the Forth and Smalltalk worlds (much better than
trying to mix them).
-- Jecel
Date: 97 Feb 07 5:37:53 am
From: Hans-Martin Mosner <hmm@heeg.de>
To: Jecel Assumpcao Jr <jecel@lsi.usp.br>
Cc: Squeak@create.ucsb.edu
Subject: Re: compiling (was: Quicktalk)
Jecel Assumpcao Jr wrote:
> One sticky problem is how to handle primitive failures
> in the same way when running as either a normal method
> or a compiled primitive. My personal choice would be
> to use a full exception mechanism, but I think that the
> solution that Self uses might come in handy:
>
> Self primitives are called using the normal send bytecodes.
> All of them can accept a block that is executed in case
> the primitive fails.
...
I would favor an approach in which the code can detect in which
architecture it is executing, i.e., whether it is executing as
a primitive or as bytecodes.
SmallInteger addition would be something like that:
(overflow check deliberately omitted to make it legible)
+ anInteger
<primitive>
RTArchitecture == ArchSqueak
ifTrue: [^self retry: #+ coercing: anInteger].
anInteger isSmallInteger
ifTrue: [^self + anInteger]
ifFalse: [^self primitiveFail]
The RTArchitecture is a kind of pseudo-variable. In the Squeak system,
it always has the value ArchSqueak. So if the method is executed
after the primitive has failed, it knows that it needs to do the
mixed arithmetic stuff.
When the Translator compiles this primitive, the RTArchitecture reference
is replaced by the constant for the appropriate architecture, such as
ArchPPC, ArchM68K, ArchX86, ArchARM, ...
With constant folding and dead code elimination, the Translator would
create code that does the following:
anInteger isSmallInteger "check argument for int tag"
ifTrue: ["convert from oop to integer, add, convert back"
^(self oopToInt + anInteger oopToInt) intToOop]
ifFalse: [^0 "the prim fail token"]
The coercing stuff is dead code and not compiled.
Being able to explicitly check for the runtime architecture would
also open the door to <gasp> in-line assembly </gasp>.
Imagine this SmallInteger method:
swapBytes
| eax |
<primitive>
RTArchitecture == ArchX86
ifTrue: [ eax := self.
self asmCode: 'BSWAP EAX'.
^eax]
ifFalse: [^(self bitAnd: 255) << 24
+ ((self bitAnd: 255 << 8) << 8)
+ ((self bitAnd: 255 << 16) >> 8)
+ (self >> 24 bitAnd: 255)]
Hans-Martin
(did I really write this?)
Date: 97 Feb 07 7:33:49 am
From: Jecel Assumpcao Jr <jecel@lsi.usp.br>
To: hmm@heeg.de
Cc: Squeak@create.ucsb.edu
Subject: Re: compiling
Hans-Martin Mosner wrote:
> With constant folding and dead code elimination, the Translator would
> create code that does the following:
Constant folding and dead code elimination are part of
what I want to get from partial evaluation.
> Imagine this SmallInteger method:
>
> swapBytes
> | eax |
> <primitive>
> RTArchitecture == ArchX86
> ifTrue: [ eax := self.
> self asmCode: 'BSWAP EAX'.
> ^eax]
> ifFalse: [^(self bitAnd: 255) << 24
> + ((self bitAnd: 255 << 8) << 8)
> + ((self bitAnd: 255 << 16) >> 8)
> + (self >> 24 bitAnd: 255)]
I would prefer the following (except that the current
translator couldn't handle it as it is polymorphic):
swapBytes
^ RTArchitecture swapBytes: self
In ArchGeneric or ArchSqueak we would have:
swapBytes: anInt
^(anInt bitAnd: 255) << 24
+ ((anInt bitAnd: 255 << 8) << 8)
+ ((anInt bitAnd: 255 << 16) >> 8)
+ (anInt >> 24 bitAnd: 255)
and in Arch486:
swapBytes: anInt
| eax |
eax := anInt.
self asmCode: 'BSWAP EAX'.
^ eax
I don't remember if the 386 has a bswap instruction (that
works!), so Arch486 might have ArchX86 as a superclass
with a longer instruction sequence.
#swapBytes *looks* like it is polymorphic and untranslatable
(and inlinable, etc). But RTArchitecture is a constant, so
we could do the lookup at compile time and inline the
result.
This solution feels "more object oriented" to me.
-- Jecel
Date: 97 Feb 07 8:15:48 am
From: Hans-Martin Mosner <hmm@heeg.de>
To: Jecel Assumpcao Jr <jecel@lsi.usp.br>
Cc: Squeak@create.ucsb.edu
Subject: Re: compiling
Jecel Assumpcao Jr wrote:
> Constant folding and dead code elimination are part of
> what I want to get from partial evaluation.
Somehow the words did not ring that bell in my head.
Of course, you're right.
>
> I would prefer the following (except that the current
> translator couldn't handle it as it is polymorphic):
>
> swapBytes
> ^ RTArchitecture swapBytes: self
>
> In ArchGeneric or ArchSqueak we would have:
>
> swapBytes: anInt
> ^(anInt bitAnd: 255) << 24
> + ((anInt bitAnd: 255 << 8) << 8)
> + ((anInt bitAnd: 255 << 16) >> 8)
> + (anInt >> 24 bitAnd: 255)
>
> and in Arch486:
>
> swapBytes: anInt
> | eax |
> eax := anInt.
> self asmCode: 'BSWAP EAX'.
> ^ eax
>
...
>
> #swapBytes *looks* like it is polymorphic and untranslatable
> (and inlinable, etc). But RTArchitecture is a constant, so
> we could do the lookup at compile time and inline the
> result.
Yes, I feel that this would be possible. The translator would
need to make some simplifying assumptions anyway, or we get to
a full dynamic Smalltalk translator in the long run. Not that
I don't want that, I just think that it might not be feasible.
So one simplifying assumption could be that 'static variables'
(globals, classes, class vars) remain static. That is, a manifest
constant can be written into a class var, and the compiler
replaces it with the actual constant in the code, not with code
to access the class var. I suspect that's what you would get with
partial evaluation if you told the compiler: 'These are constant!'.
>
> This solution feels "more object oriented" to me.
>
> -- Jecel
Yes.
Hans-Martin
Date: 97 Feb 07 10:14:13 am
From: guzdial@cc.gatech.edu (Mark Guzdial)
To: Maloney <johnm@wdi.disney.com>
Cc: Squeak@create.ucsb.edu
Subject: Re: Music in Squeak - Novice Q's
Thanks, John! In case anybody else wants another music-example-in-Squeak,
here's the best sounding version (which isn't great, but it's fun) of this
toy that I've built so-far:
'From Squeak 1.18 of December 12, 1996 on 7 February 1997 at 1:02:06 pm'!
!AbstractSound class methodsFor: 'christmas example'!
christmasIsComing
"Trying to do a three voice round"
^ MixedSound new
add: (PluckedSound namedNoteSequenceFrom:
(PluckedSound firstBar) , (PluckedSound secondBar)
, (PluckedSound thirdBar))
pan: 200;
add: (PluckedSound namedNoteSequenceFrom:
(FMSound restFor: 1) , (FMSound firstBar) ,
(FMSound secondBar) , (FMSound thirdBar))
pan: 100;
add: (PluckedSound namedNoteSequenceFrom:
(PluckedSound restFor: 2) , (PluckedSound firstBar)
, (PluckedSound secondBar) , (PluckedSound thirdBar))
pan: 300.
!
firstBar
^ #(
(c5 0.50 248)
(g4 0.375 248)
(g4 0.125 248)
(c5 0.25 248)
(c5 0.50 248)
(c5 0.25 248)
(c5 0.25 248)
(c5 0.25 248)
(b4 0.25 248)
(a4 0.25 248)
(g 1.00 248)
).
!
restFor: numBars
| restLength |
restLength _ numBars * 4.0.
^ Array with: (Array with: 'rest' with: restLength)!
secondBar
^ #(
"(rest 16.0)"
(c5 0.375 248)
(c4 0.125 248)
(c4 0.25 248)
(d4 0.25 248)
(e4 0.25 248)
(c4 0.25 248)
(e4 0.25 248)
(g4 0.25 248)
(a4 0.50 248)
(g4 0.25 248)
(f4 0.25 248)
(e4 1.0 248)
).
!
thirdBar
^ #(
"(rest 32.0)"
(e4 0.375 248)
(f4 0.125 248)
(e4 0.25 248)
(d4 0.25 248)
(c4 0.25 248)
(c5 0.25 248)
(g4 0.25 248)
(e4 0.25 248)
(f4 0.50 248)
(g4 0.25 248)
(b3 0.25 248)
(c4 1.00 248)
).
! !
--------------------------
Mark Guzdial : Georgia Tech : College of Computing : Atlanta, GA 30332-0280
(404) 894-5618 : Fax (404) 894-0673 : guzdial@cc.gatech.edu
http://www.cc.gatech.edu/gvu/people/Faculty/Mark.Guzdial.html
Date: 97 Feb 10 3:20:28 pm
From: Ian Piumarta <piumarta@prof.inria.fr>
To: squeak@create.ucsb.edu
Subject: Closures
I've done the first third of what's required to implement blocks as
full closures in Squeak. The three thirds, as I see them, are as
follows:
1) implement closures, compatibly with existing blocks;
2) remove all old-style blocks from the image, then remove
the unnecessary methods and state from BlockContext, and
steal the #blockCopy: special selector for closures to free
up a literal frame entry;
3) modify the compiler and bytecodes to support proper lexical
scopes, including block-local arguments and temporaries.
[ 3b) fix all the things that break because of assumptions
about block arguments being shared with the home context ;^) ]
Redefined blocks are now re-entrant, although there are still
"gotchas" because of args being stored in/shared with the home
context. For example, the following program is correct with redefined
blocks:
| factBlock |
factBlock _ [ :n |
n > 0
ifTrue: [n * (factBlock value: n - 1)]
ifFalse: [1]].
^factBlock value: 3
(it won't work at all with traditional Squeak blocks) although a
head-recursive version would return the wrong result because the
argument would get clobbered by the recursive invocation before its
last use.
Closure creation is slightly (3%) faster than #blockCopy:, although
invocation is slower (about 2.5 times) because of the overhead of
creating a new BlockContext on every send of #value. (The overall
impact on performance would be a lot lower, although I've not yet got
round to recompiling my entire image and timing various things.)
I was going to post the changes to the list, but since they are quite
long (30K) I have decided not to do this. If you'd like to try out
redefined blocks then let me know and I'll send you the change set
direct, with instructions on how install it and rebuild your VM.
If there is sufficient interest then I will consider doing the other
2/3rds of the job... ;-)
Regards,
Ian
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes a Objets Repartis -----------------------
Date: 97 Feb 11 4:57:19 pm
From: Ken Greene <krg@nfuel.com>
To: squeak@create.ucsb.edu
In-Reply-To: <199702102330.AAA21459@prof.inria.fr>; from "Ian Piumarta" at Feb 11, 97 12:30 (midnight)
Subject: Re: Closures
> If there is sufficient interest then I will consider doing the other
> 2/3rds of the job... ;-)
I think this is worthwhile and it would remove one of the
limitations of Squeak. I do not currently have the ability
to generate a VM or I would volunteer to test the
implementation.
Regards,
Ken Greene
______________________________________________________________________
Siemens Power Corp EMail: krg@nfuel.com
2101 Horn Rapids Road - P.O. Box 130
Richland, WA 99352-0130
______________________________________________________________________
Date: 97 Feb 12 7:45:10 am
From: joel@ObjectPeople.com
To: squeak@create.ucsb.edu, Ian Piumarta <piumarta@prof.inria.fr>
Subject: Re: Closures
> If there is sufficient interest then I will consider doing the other
> 2/3rds of the job... ;-)
Ian.
I would like to test your changes.
I'm running the NT (3.51) version. Getting my hands on a compiler
right now.
Thanx.
Joel
Joel Lucuik | The Object People
Joel@ObjectPeople.com | Your Smalltalk Experts
613.225.8812 (V) 613.225.5943 (F) | http://www.objectpeople.on.ca
"Where's the kaboom? The EARTH-SHATTERING kaboom????
-Marvin the Martian"
Date: 97 Feb 12 7:56:28 am
From: Paul Fernhout <kfsoft@netins.net>
To: Stefan Matthias Aust <sma@kiel.netsurf.de>
Cc: squeak@create.ucsb.edu
Subject: Re: Merging Forth and Smalltalk
Stefan -
Thanks for all your helpful comments and Smalltalk in Forth examples.
It looks like the Forth & Smalltalk thread is loosing steam and being
replaced by "Walk Tall and Talk Small" optimized smalltalk. No hard
feelings to anyone involved - I for one would be happy to see an
optimized Squeak and do all my low level coding in Smalltalk. I've just
been too busy recently to post anything more on this subject, which is
another reason I didn't get back to you sooner.
Thanks for the all your comments on this topic, including the short
synopsis of the German postings to de.comp.lang.forth.
In response to two issues you raised:
I don't know of any documentation of the Forth bootstrap process. What
I do know is that usually it is done as a cross compile from another
Forth system. It wouldn't surprise me if this was documented somewhere.
Forth has a strong tradition of metacompilation.
On sharing my Forth in Smalltalk:
I put it on our website. You can download it from:
http://www.gardenwithinsight.com/squeak/forth.st
You need the entire path as there is no way to get to it from the main
page. It's about 15K as a VisualWorks filein. Most of the code is
examples of how to use the very simple interpreter core.
Please let me know if you have any problems loading it.
It contains two attempts at Forth in Smalltalk
in Visual Works 2.5.1 filed out from under ENVY.
These are both pretty rough - a few hours work a month back in my spare
time. You can ignore the first extension to Symbol which was for
convenience and is used in some examples..
The two classes in this file-in are ForthInterpreter and SmallForthVM.
ForthInterpreter lets you put in Forth like expressions and evaluate
them (including defining new forth words.)
SmallForthVM is a copy (ick!) of ForthInterpreter modified to send
messages to Smalltalk objects on the stack instead of interpreting them.
The first comes with twenty-nine example expressions. The second
reworks the first two of those to show the difference in syntax, and
then adds three more examples.
This code is very rough, but it is just a proof of concept....
It isn't a complete Forth implementation by any means, nor does it
include the Forth Builds>Does> features and such. Nonethless, I think
it is an amusing thing to show how little code it actually takes...
The one trick is the use of the 'meta' word (also referred to as '.' and
'push and 'data') which pushed the next item on the stack instead of
interpreting it. In an intermediate version you had to use data to push
any literal; I changed that so now it automatically pushes anything
except a symbol, but some of the examples still reflect that earlier
version (although they still work with the latest version).
Some examples in case you don't want to load the code:
This is an example of the code to do two fahrenheight to celcius
conversions in a forth-like way
and print the result to the transcript:
|interpreter|
interpreter := ForthInterpreter new.
"define a function"
interpreter interpret: #(
(32 minus 5 9 divide times )
data f_to_c
define
).
"call it twice"
interpreter interpret: #(32 f_to_c print cr).
interpreter interpret: #(212 f_to_c print cr).
The above using the second interpreter.:
|interpreter|
interpreter := SmallForthVM new.
"define a function"
interpreter interpret: #(
(32 - 5 9 / * )
. f_to_c
vm define
).
"call it twice"
interpreter interpret: #(32 f_to_c vm print vm cr).
interpreter interpret: #(212 f_to_c vm print vm cr).
Note the special 'vm' word to push the vm on the stack so you can send
messages it.
In the first class, the VM gets all the messages.
In the second class, they only go to objects on the stack.
'.' is used to push things on the stack.
The following defines a function with the newer interpreter with
Smalltalk message sends (used for '=')
and calls it do do some rather insecure Zork-like password prompting:
SmallForthVM new interpret: #(
('Please enter the password' vm request)
. passwordPrompt vm define
passwordPrompt 'swordfish' =
('password correct' vm warn)
('password invalid - access denied' vm warn)
vm ifTrueFalse
).
'warn' puts up a message dialog. 'request' puts up a dialog that asks
for a line of input. Note that arrays in this system act sort of like
blocks. This system also relies on VW not requiring a '#' in front of
symbols embedded in arrays. I think this is OK in Squeak too.
By the way, this code could be used as run-time interpreter add-on for
VisualWorks with the addition of something to read in files and create
arrays of literals.... Please credit me and reference my web site
http://www.gardenwithinsight.com if you use it in projects.
-Paul Fernhout
kfsoft@netins.net
========================================
Download a public beta release of our garden simulator at:
http://www.gardenwithinsight.com
Date: 97 Feb 12 9:25:53 am
From: stp (Stephen Travis Pope)
To: squeak@create.ucsb.edu
In-Reply-To: Ken Greene <krg@nfuel.com>'s letter of: 97 Feb 11
Subject: Re: Closures
> If there is sufficient interest then I will consider doing the other
>
2/3rds of the job... ;-)
GREAT IDEA--sign me up to test it (and to port loads of code that uses "new"
block semantics).
stp
Stephen Travis Pope, Center for Research in Electronic Art Technology
(CREATE), Department of Music, U. of California, Santa Barbara (UCSB)
Editor--Computer Music Journal, MIT Press
stp@create.ucsb.edu, http://www.create.ucsb.edu/~stp/
Date: 97 Feb 12 11:18:08 am
From: Stefan Matthias Aust <sma@kiel.netsurf.de>
To: squeak@create.ucsb.edu
Subject: Re: Closures
Hi!
>Closure creation is slightly (3%) faster than #blockCopy:, although
>invocation is slower (about 2.5 times) because of the overhead of
>creating a new BlockContext on every send of #value. (The overall
Did you already consider the optimization of common cases like blocks
without free variables (variables defined outside, but used inside the
block), which need no own context? Otherwise this should reduce the speed
penality.
bye
--
Stefan Matthias Aust // Too much truth is unhealthy...
http://www.kiel.netsurf.de/users/s/sma/
Date: 97 Feb 12 11:45:33 am
From: Dan Ingalls <DanI@wdi.disney.com>
To: Paul Fernhout <kfsoft@netins.net>
Cc: Squeak@create.ucsb.edu
In-Reply-To: <3301EBA1.33E7@netins.net>
Subject: Re: Merging Forth and Smalltalk
>It looks like the Forth & Smalltalk thread is loosing steam and being
>replaced by "Walk Tall and Talk Small" optimized smalltalk.
I hope I haven't thrown a wet blanket on this approach. =20
It's true that I will always pull Squeak toward everything-in-Smalltalk. =
That's my thing. But that doesn't mean that you shouldn't also have your=
thing. I think Squeak/Forth is quite doable, and it could be a *lot of=
fun* for a Squeaker who is into Forth. I might criticize a design, but I=
would never knock having fun!
- Dan
Date: 97 Feb 12 3:37:47 pm
From: Ian Piumarta <piumarta@prof.inria.fr>
To: sma@kiel.netsurf.de
Cc: squeak@create.ucsb.edu
Subject: Re: Closures
Stefan,
> Did you already consider the optimization of common cases like blocks
> without free variables (variables defined outside, but used inside the
> block), which need no own context?
All blocks need a context since there's no way to know if it's safe to
execute an arbitrary block on top of the caller's stack, regardless of
whether or not the block is provably "strictly LIFO". (Like most
things I claim, this almost certainly isn't true: but the runtime
effort to detect the optimisable cases would certainly not be worth
it.)
I spent this evening poking around inside the compiler (it's a *long*
time since I saw its "close relative" in PS2.2/3 -- a bit like bumping
into a long-lost enemy! ;-) and I think the changes required to
support full closures are not as trivial as I originally thought. For
example, each block *must* compile into a separate method -- otherwise
there's nowhere to encode the required frame size, number of temps,
etc. Until this is done, the closure stuff isn't really that
interesting. There will be more changes to that anyway: a closure
will have to hang onto its associated "block method", BlockContexts
themselves need changing to hang onto their lexically enclosing
contexts, and a new bytecode or two is needed for push/pop/store
inside this "context display".
Pile on top of this the changes which will be required in the
debugger, and it adds up to a bit more than the weekend project which
I had hoped for.
It does, however, open the door to some very important improvements in
the semantics of the language, the possibility of support for other
"embedded" languages (even directly on top of the Squeak bytecodes),
and possible future VM optimisations. And I also think that I have a
plan about how to change the compiler "minimally" to do what's
necessary. (I've already put in some code to track lexical nesting
and provide local binding and encoding of args/temps in outer
contexts.) I therefore don't intend to give up just yet...
Regards,
Ian
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes a Objets Repartis -----------------------
Date: 97 Feb 13 5:36:40 am
From: jesse@sunpool.CS.Uni-Magdeburg.De (Roland Jesse)
To: squeak@create.ucsb.edu
In-Reply-To: <v03007802aed7ed855d70@[206.16.10.79]>
Subject: mysterious ld errors while compiling Squeak 1.18
While trying to make Squeak on a FreeBSD (2.2) box I got some
mysterious ld messages:
gcc -o SqueakVM InterpTestInline.o sqFilePrims.o sqSoundPrims.o sqUnixDirectory.o sqUnixJoystick.o sqUnixSound.o sqXWindow.o -lX11 -lm
ld: InterpTestInline.o: unexpected multiple definitions of symbol `selector:V1', type 0x21
Ì:1: Definition of symbol `selector:V1' (multiply defined)
ld: InterpTestInline.o: unexpected multiple definitions of symbol `selector:V1', type 0x21
...
Everything before compiled well after changing some constants in
InterpTestInline.c to 'unsigned long'. (BTW: Why are 4*10exp9 numbers
'int' and not as constants defined but hardcoded on every place they
are used?)
Thanks for any hints in advance,
Roland
--
+-------------
| Roland Jesse <jesse@cs.uni-magdeburg.de>
| http://www.cs.uni-magdeburg.de/~jesse/ |
-----+
Date: 97 Feb 13 6:38:10 am
From: Ian Piumarta <piumarta@prof.inria.fr>
To: sma@kiel.netsurf.de
Cc: squeak@create.ucsb.edu
In-Reply-To: <1.5.4.32.19970212192707.006af518@kiel.netsurf.de> (message from
Stefan Matthias Aust on Wed, 12 Feb 1997 20:27:07 +0100)
Subject: Re: Closures
Stefan,
I think I might have misinterpreted your message...
> Did you already consider the optimization of common cases like blocks
> without free variables (variables defined outside, but used inside the
> block), which need no own context?
^^^
Do you mean a local context for the block's activation, or "home" context?
The latter makes much more sense in the context of blocks without free
variables, although I took your meaning as the former when I replied last
night.
I agree entirely that the "latter" interpretation is important with blocks as
lexically scoped closures. In the traditional blocks definition you need to
stabilise (allocate on the heap) the context for the block (in case it's
stored someplace) and the home context (so that the block can refer to its
local state). With redefined blocks you potentially have to stabilise the
block's context, the home context, and every context between them in the
"display".
If you look at some of the commercial implementations you will see that they
go to a lot of trouble to optimise such free references. A single free
reference which is not used outside the block is often stored in a slot in
the closure as a "copied value". Multiple free references are copied into an
array and then the array is stored in the "copied values" slot of the
closures which share it. (This also effectively "flattens" the display,
making references to free variables from very "distant" outer contexts much
cheaper to access: it costs one additional indirection [to the copied values
array] instead of N indirections to follow the context chain down N levels in
the display.)
This is a lot of additional work in the compiler, but could be worth the
trouble if the cost of context stabilisation is a significant factor in
overall performance. It's hard to know if this will be worth the trouble in
Squeak until closures are implemented properly, so that measurements can be
made.
Ian
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes a Objets Repartis -----------------------
Date: 97 Feb 13 7:03:05 am
From: Ian Piumarta <piumarta@prof.inria.fr>
To: jesse@eva.cs.Uni-Magdeburg.DE
Cc: squeak@create.ucsb.edu
In-Reply-To: <199702131346.OAA28243@pflaume.cs.uni-magdeburg.de>
(jesse@eva.cs.Uni-Magdeburg.DE)
Subject: Re: mysterious ld errors while compiling Squeak 1.18
Roland,
> While trying to make Squeak on a FreeBSD (2.2) box I got some
> mysterious ld messages:
...
> ld: InterpTestInline.o: unexpected multiple definitions of symbol `selector:V1', type 0x21
I don't know why this happens. However...
We are expecting some PCs to arrive tomorrow, and I will be installing
FreeBSD 2.1.5 on at least one of them. I'll try compiling Squeak on it and
keep you posted about any problems and solutions.
The contents of InterpTestInline.c are odd because that file is generated
automatically by a Smalltalk->C translator (the VM is written in Smalltalk).
The "signed constant so big that it is unsigned" warning messages from gcc
are completely harmless -- gcc does the right thing with them in all cases.
Your problem might be due to a mistake when altering the constants. Have you
tried compining it with the original InterpTestInline.c, ignoring the warning
messages?
> Thanks for any hints in advance
Let me know how you get on. If you can be patient until the weekend then I
will also have a FreeBSD system on which to "compare notes" with you. I will
also be able to make a precompiled binary VM available for i586/freebsd2.1.
Regards,
Ian
------------------------------- projet SOR -------------------------------
Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr
BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87
----------------------- Systemes a Objets Repartis -----------------------
Date: 97 Feb 13 7:31:36 am
From: jesse@sunpool.CS.Uni-Magdeburg.De (Roland Jesse)
To: Ian Piumarta <piumarta@prof.inria.fr>
Cc: squeak@create.ucsb.edu
In-Reply-To: <199702131512.QAA18984@prof.inria.fr>
Subject: Re: mysterious ld errors while compiling Squeak 1.18
Ian Piumarta writes:
> Your problem might be due to a mistake when altering the constants. Have you
> tried compining it with the original InterpTestInline.c, ignoring the warning
> messages?
Yes, I tried - without success. Of course I didn't the replacing
purely by hand, emacs' search'n'replace needed to take the job and did
it well. ;)
> Let me know how you get on. If you can be patient until the weekend then I
> will also have a FreeBSD system on which to "compare notes" with you. I will
> also be able to make a precompiled binary VM available for i586/freebsd2.1.
Ok. It may be probably interesting if there occur some differences
between 2.1.5 and 2.2 (or -current).
Regards,
--
+-------------
| Roland Jesse <jesse@cs.uni-magdeburg.de>
| http://www.cs.uni-magdeburg.de/~jesse/ |
-----+
Date: 97 Feb 14 3:03:25 pm
From: Stefan Matthias Aust <sma@kiel.netsurf.de>
To: squeak@create.ucsb.edu
Subject: Re: Closures and dynamically inlining
Hello Ian!
>Stefan,
>
>I think I might have misinterpreted your message...
>
>> Did you already consider the optimization of common cases like blocks
>> without free variables (variables defined outside, but used inside the
>> block), which need no own context?
> ^^^
>Do you mean a local context for the block's activation, or "home" context?
I was probably too vargue here. I indeed meant the later. Each invoked
method needs something to store its local state in, consisting mainly of
local variable values and a connection to the calling method. You can call
this (method) context or activation record. Because of its LIFO stack-like
nature it can be (and often is) implemented with a stack, for example the
processors system stack.
With (block) closures this is different. As every function or method, they
generally need a state holder, too. This can be called (block) context or
the (block) closure (because a so called block closure is really an unnamed
(lambda) function to names are easily confused) A closure does not only
contain a local state but as it can in general refer to variables, defined
outside its function (so called free variables), it has to refer to this
outside context, too.
Unfortunately closures aren't LIFO anymore and a non-LIFO block with free
variables keeps its outer context alive (breaking their LIFO nature), too.
With Smalltalk, only blocks can (fortunately) have lexically bound free
variables (in LISP, both named functin and unnamed lambda expression may
have free variables -- and variables may be bound either lexically or
dynamically -- introducing even more complexitiy.)
Lexical binding means that the free variables inside the block always refer
to that variables which are defined in the method, which contains the block
-- and not refering to variables of the same name in the method that invokes
(calls) the block.
So, in general, Smalltalk needs heap allocated method contexts (to support
non-LIFO-structures) and heap allocated block closures, which refer to
method context
--> method - the currently executed method
--> arguments
--> temporaries
--> previous - caller's context or closure
--> receiver - the object for which this is executed
block closure
--> block, the currently executed block code
--> arguments
--> temporaries
--> previous - caller's context or closure
--> home context - lexically method context
The latter is needed to implement "^" inside blocks which will return from
the block's method and not only the block. Please note that a closure has no
receiver.
But heap contexts are considered harmful to performance (even if a once read
a paper related to either the self project or written by Henry Baker, I
don't remember anymore, which tried to show that heap allocated contexts
need not be slower than stack contexts (although, they are never faster).
>I agree entirely that the "latter" interpretation is important with blocks as
>lexically scoped closures. In the traditional blocks definition you need to
>stabilise (allocate on the heap) the context for the block (in case it's
>stored someplace) and the home context (so that the block can refer to its
>local state).
Yes. And as you mentioned in your previous email, I know VisualWork's
implementaion of blocks and their optimizations here. And no, I think, that
the optimization overhad is worth the work because #do: loops and other
block invokations are *very* common in Smalltalk and would *hate* so see
code like the one in (for example) VisualWork's KeyboardProcessor class,
where a (-omitted-) programmer always used for/next loop instead of more
elegant enumeration methods, probably for speed reasons only. (This class
also gives an example of a tricky three-state logic featuring 0, 1 and nil
and is in generall a good example of how-to-program-NOT in Smalltalk. :-)
How to optimize the general case shown above? Methods without blocks (and
without references to the pseudo variable "thisContext") need no heap
allocated context at all. But even with block there's some hope.
A block which neither perform a non-local return ("^") nor has free
variables (also called closed block) (and again didn't contain
"thisContext") need no reference to a home context and the defining method
can still use a stack allocated context. The block needs a closure, but it
can be contant (per process, to keep reentrance) if the invoking primitive
will reset all temporaries.
A block with free variables, which are used for reading only -- please
notice, that "self" is a free variable, too -- can use copied values and as
a consequence, don't need a reference to a defining method context.
But there's still hope. Even if the block does bad things to its entrusted
free variables, no method context reference is needed, if one can proof,
that the block doesn't violate the LIFO property. This can be trivially
proven, if the blocks isn't used as method argument or return value and if
it isn't stored into a non-temporary variable. Because this doesn't already
cover a great number of cases, one probably will introduce well-behaving
methods (for example #do:) which guarantee not to violate LIFO. Changed free
variables are copied back after invocation or -- probably the better
alternative -- are directly allocated inside the block closure and the
method will refer its variables via the closure.
Even a non-local-return inside a LIFO block is possible without sacrifing
stack contexts. This context will contain a reference to the privious
context, and if it is possible, to unwind a number (more than one) of stack
allocated contexts at once, the block can do this, too.
Btw, to speed up execution even more, what's about dynamically inlining
enumeration methods to break them into simpler for/next loops which are then
again inlined by the compiler.
To inline
| s | s := 0. #(1 2 3) do: [:e | s := s + e]. s
the compiler first has to determine (dynamically), that the #do: in the
example above is very often (or even always) send to an instance of Array.
So it grabs the implementation of Array>do: and rewrite the code
| s | s := 0. 1 to: #(1 2 3) size do: [:e | s := s + e]. s
which is (or at least coul be) again rewritten by the compiler's macro
replacement to
| s t1 t2 t3 | s := 0.
t1 := 1. t2 := #(1 2 3). t3 := t2 size.
[t1 <= t3] primitveWhile:
[[:e | s := s + e] value: (t2 at: t1). t1 := t1 + 1].
s
and once more to
| s t1 t2 t3 | s := 0.
t1 := 1. t2 := #(1 2 3). t3 := 3 "constant evalation".
[t1 <= t3] primitveWhile:
[| e | e := (t2 at: t1).
s := s + e. t1 := t1 + 1].
s
and finally to (with constant propagation and bound renaming)
| s t1 | s := 0. t1 := 1.
[t1 <= 3] primitiveWhile: [s := s + (#(1 2 3) at: t1). t1 := t1 + 1].
s
#primitiveWhile is then transformed into test and jump instructions inside
the virtual machine.
The replacements shown above are only applications of standard pattern. The
trick is however, how to choose the right method to inline and when to
inline. Assuming for the moment, we would know what method to pick, how do
we deal with changes to the inlined method?
My first idea here would be, to make my method a dependent of the Array>do:
method to be notified if that method is changed.
Comments?
(Just in case: Standard disclamer: above shown are *my* thought only)
bye
--
Stefan Matthias Aust // Too much truth is unhealthy...
http://www.kiel.netsurf.de/users/s/sma/
Date: 97 Feb 18 5:27:14 pm
From: Jon@AppliedThought.com (Jon Hylands)
To: squeak@create.ucsb.edu
Subject: Hello, Win95 problems...
Hi all,
I just subscribed to the list.
I have been running 1.13 on my P166 (Win95) for the last few months.
Recently, I decided to try & upgrade to a later version (1.16). I got the=
4
required files (image, changes, sources, & VM executable). The problem I =
am
having is the executable will not load the image. I can run the =
executable
by itself, and it comes up with the little window saying "Useage: squeak
<imageFile>".
So, I know the executable is sort of okay, but when I drag the image onto
it, it gets an illegal instruction error. The error box details say:
SQUEAK caused an invalid page fault in
module SQUEAK.EXE at 0137:0040b80c.
Registers:
EAX=3D00000000 CS=3D0137 EIP=3D0040b80c EFLGS=3D00010206
EBX=3D00790118 SS=3D013f ESP=3D0066fd18 EBP=3D00000000
ECX=3D0a0d9500 DS=3D013f ESI=3D00000008 FS=3D4b2f
EDX=3D00000000 ES=3D013f EDI=3D00210000 GS=3D0000
Bytes at CS:EIP:
8b 04 19 83 e0 03 83 f8 01 7e 04 33 f6 eb 12 75=20
Stack dump:
0057f700 00000040 00210000 001aee00 0042fe68 0040b16c 00210000 00000040
00210000 00401b44 00210000 0066fe38 0042be6c 00000000 815e3e93 00402976=20
Any clues as to what's happening?
BTW, In 1.13 I get about 7.2 million bytecodes/second on my machine :-)
Later,
Jon
--------------------------------------------------------------
--- Jon Hylands -- Jon@Ftn.net --- http://www.ftn.net/~jon ---
--------------------------------------------------------------
----- PGP Fingerprint: 72 0B 9D E3 C2 F0 5D AC ---------------
---------------------- E3 D3 3D D0 7B 21 2B 2E ---------------
--------------------------------------------------------------
Date: 97 Feb 20 1:16:32 am
From: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
To: squeak@create.ucsb.edu
Subject: There is something definitely wrong here (Was: Hello, Win95 prob
Hi,
> So, I know the executable is sort of okay, but when I drag the image onto
> it, it gets an illegal instruction error. The error box details say:
Ok, after looking into the problem I encountered the following
problem. The byte reversal code from the interpreter is wrong.
The reverseBytesInImage() function reverses _everything_ in the
image - including the byte codes!
How has anyone ever managed to start an image requiring byte code
reversal?! This question applies in particular to Ian (do you use
the code from the interpreter or still your own (working) code in
sqSaveRestore.c?) and to John (didn't you say you were able to load
images requiring byte reversal?). I on my own have to say that all
the reversed images I'm using have been created before upgrading the
VM to 1.18 - so these images are working because at this time the code
from Ian was used. The images on the FTP-server do have Mac byte
order - I did the add-ons of DosFileDirectory and the like on a Mac
and put them as-is on the server.
Well, maybe I'm missing something here.
Any help would be greatly appreciated,
Andreas
PS. As a quick fix for Jon, I'll put a new version to
http://simsrv.cs.uni-magdeburg.de/~raab/squeak/beta
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics Phone: +49 391 671 8065 I
I University of Magdeburg, Germany Fax: +49 391 671 1164 I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+
Date: 97 Feb 20 2:09:48 am
From: Hans-Martin Mosner <hmm@heeg.de>
To: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
Cc: squeak@create.ucsb.edu
Subject: Re: There is something definitely wrong here (Was: Hello, Win95 prob
Andreas Raab wrote:
>
> Hi,
>
> > So, I know the executable is sort of okay, but when I drag the image onto
> > it, it gets an illegal instruction error. The error box details say:
>
> Ok, after looking into the problem I encountered the following
> problem. The byte reversal code from the interpreter is wrong.
> The reverseBytesInImage() function reverses _everything_ in the
> image - including the byte codes!
>
> How has anyone ever managed to start an image requiring byte code
> reversal?!
If you look a little closer, you will see that there is a method
byteSwapByteObjects that unreverses the byte objects, including the bytecode
parts of CompiledMethods. So this track is probably not the right one.
FYI, I am running an 1.18 image copied from my mac on Windows NT without any
problems. I generated the VM with the 1.18 Interpreter class and your Windows
C code using VC++ 2.0...
Date: 97 Feb 20 8:32:08 am
From: guzdial@cc.gatech.edu (Mark Guzdial)
To: squeak@create.ucsb.edu
Subject: Another WinSqueak Q: Allocating More Memory
This is probably a Windows-thing not a Squeak-thing: How do I allocate more
memory to the Windows version of Squeak? I have a student who's porting
some of my standard class demonstrations to Squeak. He's having no problems
in Linux or on Mac, but he's running out of memory in Windows.
Thanks!
Mark
--------------------------
Mark Guzdial : Georgia Tech : College of Computing : Atlanta, GA 30332-0280
(404) 894-5618 : Fax (404) 894-0673 : guzdial@cc.gatech.edu
http://www.cc.gatech.edu/gvu/people/Faculty/Mark.Guzdial.html
Date: 97 Feb 20 9:42:30 am
From: Tim Rowledge <rowledge@interval.com>
To: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
Cc: Squeak mailinglist <squeak@create.ucsb.edu>
In-Reply-To: <158B057C76@isg_nw.cs.uni-magdeburg.de>
Subject: Re: There is something definitely wrong here (Was: Hello, Win95 prob
On Thu 20 Feb, Andreas Raab wrote:
> Ok, after looking into the problem I encountered the following
> problem. The byte reversal code from the interpreter is wrong.
> The reverseBytesInImage() function reverses _everything_ in the
> image - including the byte codes!
...and then the compiledmethods, strings etc are re-reversed later.
It was marginally quicker to reverse all memory (leaving oops, header
words etc in the correct form) and then 'correct' the byte stuff.
It's been working just fine on my Acorn for ages, so it's unlikely to
be the cause of your problems.
What might, just possibly, be your problem is the Float stuff:- IIRC
Ian had to WORD reverse floats as well as byte swap them, whereas
IEEE spec doesn't do that. The 1.18 stuff sticks with IEEE, so you
may need to worry about the macros in sq.h that deal with
DOUBLE_WORD_ALIGNMENT.
--
Tim Rowledge: rowledge@interval.com (w) +1 (415) 856-7230 (w)
tim@sumeru.stanford.edu (h) <http://sumeru.stanford.edu/tim>
Date: 97 Feb 20 10:25:56 am
From: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
To: Hans-Martin Mosner <hmm@heeg.de>
Cc: squeak@create.ucsb.edu
Subject: Re: There is something definitely wrong here (Was: Hello, W
> Hans-Martin Mosner wrote:
> If you look a little closer, you will see that there is a method
> byteSwapByteObjects that unreverses the byte objects, including the bytecode
> parts of CompiledMethods. So this track is probably not the right one.
Aaarrggghhhh! I AM SO STUPID! I've been using the old non-working piece of
code which was in 1.18 before John fixed it. Don't ask me why...
Thanks a lot - I was really loosing faith in that thing.
- Andreas
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics Phone: +49 391 671 8065 I
I University of Magdeburg, Germany Fax: +49 391 671 1164 I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+
Date: 97 Feb 20 10:56:38 am
From: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
To: guzdial@cc.gatech.edu (Mark Guzdial)
Cc: squeak@create.ucsb.edu
Subject: Re: Another WinSqueak Q: Allocating More Memory
Hi,
> This is probably a Windows-thing not a Squeak-thing: How do I allocate more
> memory to the Windows version of Squeak? I have a student who's porting
> some of my standard class demonstrations to Squeak. He's having no problems
> in Linux or on Mac, but he's running out of memory in Windows.
This is sort of difficult, since Squeak does not (yet?!) support
dynamically growing memory. I've been using either 4 MB or the size
of the image (provided that it exceeds 4 MB in size).
I'm not really familiar with the memory layout of Squeak but I would
like to know what actually needs to be done if you want to add some
new space after the current endOfMemory. I'm thinking of using
virtual memory for this, so moving memory contents would not be
necessary.
- Andreas
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics Phone: +49 391 671 8065 I
I University of Magdeburg, Germany Fax: +49 391 671 1164 I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+
Date: 97 Feb 21 11:28:33 am
From: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
To: John Maloney <johnm@bobo.rd.wdi.disney.com>
Cc: squeak@create.ucsb.edu
Subject: Re: There is something definitely wrong here
> John Maloney <johnm@bobo.rd.wdi.disney.com> wrote:
> No, *I* am so stupid! I apologize for not having gotten it right the first
> time and
> have no excuse, since I had working code from two people to work from. :->
No, it's really not your fault. I suppose the problem was due to the following
order of operation (as far as I can reconstruct it):
a) Get the 1.18
b) Run it (works fine with Ians byte reversal) and save it
c) Get the 1.18a, run it and save it (byte reversal done here)
d) Generate a VM from 1.18a
e) Compile it
f) Note the problem with getLongFromFile:swap:
g) Use the 1.18 (!!!!) to fix the problem :-((((
h) Generate a VM from 1.18
Since in g) I used the 1.18 (probably because it was in the compilers
debug options at this time) and the byte reversal in the 1.18a was
already done in c) I've never noticed the problem later on. There is
no reason to blame you - I'm the stupid guy here ;-))
Bye,
Andreas
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics Phone: +49 391 671 8065 I
I University of Magdeburg, Germany Fax: +49 391 671 1164 I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+
Date: 97 Feb 22 10:43:08 am
From: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
To: squeak@create.ucsb.edu
Subject: Time for an update
Hi Win-Squeakers,
seems that it's time for an update of the VM. I've done so and
it's already available at
http://simsrv.cs.uni-magdeburg.de/~raab/squeak/
and will be on the usual ftp servers in the next few days. The major
improvements are:
a) a working ;-) pre-compiled VM
b) some Win95 specific bug fixes
c) the interrupt key is now taken from the image
(NOTE: This will modify the interrupt key to Alt-"." unless you
change it. For convenience I've left the Ctrl-Break combination
as additional interrupt key)
d) A rudimentary virtual memory support. The advantage of it is that
you can now use up to 16MB of RAM while avoiding the waste of
memory which could be used by other applications. Generally, I would
prefer a more decent and transparent memory management (this one
is sort of a hack) - but it works and those people having problems
with the available memory should now be satisfied ;-)
Hope you like it,
Andreas
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics Phone: +49 391 671 8065 I
I University of Magdeburg, Germany Fax: +49 391 671 1164 I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+
Date: 97 Feb 23 7:45:25 am
From: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE>
To: Dwight Hughes <dhughes@intellinet.com>
Cc: squeak@create.ucsb.edu
Subject: Re: Time for an update -- a problem on NT 4.0
Hi,
> Whenever I try to resize or move or collapse any window it locks up
> and I have to kill the Squeak process. Once it gave me an out of memory
> message from Squeak, after I let it sit for a while (not likely on 32MB RAM
> and 95MB of virtual memory - since Squeak was the only non-OS process
> running).
I've just seen the same problem when I went to Win95. The problem is
- again - the byte-order, but this time of the floats. Before 1.18
Ian's code for byte reversal reversed the floats in the image, but
since 1.18 floats are required to be in Mac-order (they are reversed
on the fly if necessary). I didn't note this as a problem unless I tried
with several different versions. Now, your problem is due to the
fact that the 1.18 image is in Mac-Order and I had (for backward
compatibility) assumed that floats are in host byte order. Your
problem is most likely to be an infinite recursion loop in
Float>>truncated or Float>>floorLog. So, what we can do is reversing
the floats on the fly.
Unfortunately, this raises some problems. If you're using an image which
has been stored by the pre-1.18 version, all of the floats are already
in X86 order. If one now uses the new VM version these floats are
reversed again and you'll end up with the same problem as before.
Therefore, I have now put two programs on the server:
1) bin/squeak.exe
This version uses floats in Mac byte order (and should fix your
problems). Note, that this version will not run correctly with
byte-reversed images stored with older VM versions.
2) bin/reverseFloats.exe
This reverses all the floats in a given image file. You should
only use this if you're running into trouble with the floats
(btw, this can be easily detect by just doing a printIt on any
float value, such as "42.0" since the print method of Float will
not work correctly with the wrong byte order).
I highly recommend to get the new VM version in particular if you
want to exchange images from 1.18 (or later) between different
platforms.
Sorry for the inconvenience,
Andreas
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics Phone: +49 391 671 8065 I
I University of Magdeburg, Germany Fax: +49 391 671 1164 I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+
Date: 97 Feb 28 9:42:02 am
From: Dan Ingalls <DanI@wdi.disney.com>
To: Squeak@create.ucsb.edu
Subject: Space saving tweak
For folks interested in running with minimal footprint, the following change (insertion of the commented line) will release the backing bitmap for the active window. Of course it won't help if you have already disabled cached window bits entirely.
!StandardSystemController methodsFor: 'basic control sequence'!
controlInitialize
view displayEmphasized.
view uncacheBits. "Release cached bitmap while active"
sensor waitNoButton.
status _ #active! !
Date: 97 Feb 28 1:21:27 pm
From: mccullough@interval.com (Paul L. McCullough)
To: Squeak@create.ucsb.edu
Subject: improvements to IdentityDictionary & IdentitySet
I notieced that IdentityDictionary and IdentitySet do not use identityHash
for their initial probe.
The following chunks fix those problems. Note that chunk filein order is
important...
paul
=====
"This file has been ordered by hand -- chunk order is very important"!
!Set methodsFor: 'private'!
hashOf: anObject
^anObject hash! !
!IdentitySet methodsFor: 'private'!
hashOf: anObject
^anObject identityHash! !
!IdentityDictionary methodsFor: 'private'!
hashOf: anObject
^anObject identityHash! !
!SmallInteger methodsFor: 'comparing'!
identityHash
^self! !
!Set methodsFor: 'private'!
findElementOrNil: anObject
"Answer the index of a first slot containing either a nil
(indicating an empty slot) or an element that matches the given object.
Answer the index of that slot or zero. Fail if neither a match nor an empty
slot is found."
| start index length |
"search from (hash mod size) to the end"
length _ array size.
start _ ((self hashOf: anObject) \\ length) + 1.
index _ self scanFor: anObject from: start to: length.
index > 0 ifTrue: [ ^ index ].
"search from 1 to where we started"
index _ self scanFor: anObject from: 1 to: start - 1.
index > 0 ifTrue: [ ^ index ].
"Bad scene. Neither have we found a matching element
nor even an empty slot. No hashed set is ever supposed to get
completely full."
self error: 'There is no free space in this set!!'.! !
IdentitySet allInstances do: [:x | x rehash].
IdentityDictionary allInstances do: [:x | x rehash]!
stp@create.ucsb.edu]
Created: 1996.11.08; LastEditDate: 1996.11.11