Andreas Raab andreas.raab@gmx.de wrote:
Hi,
Andreas Raab andreas.raab@gmx.de wrote: I understand the problem, but you're implicit about the solution - do you mean that instead of todays remove we would change the Morphs parent to be the world?
No, what I'm saying is that the "owner" relationship should not be affected at all when you "remove" a morph.
Ah. It seems to me though we can keep the invariant you describe below (isParent(A,B) iff isSubmorph(B,A)) and still solve the problem. What do you think about fixing the issue the way I propose - every Morph always starts out with a parent (AstralWorld? WombWorld?), and can only change parents, but never remains orphaned. AFAICT, this would not change many implementation issues, but would require eventually changing the interfaces so that the remove would be replaced with #reParentTo: or something like it.
Secondly, there is a significant problem when creating new morphs. These days, new morphs are not initialized in a definitive context (e.g., when they are created their owner is nil) and one would need to provide appropriate initializations. Most places don't care about this at all and I would suspect that we'd get into serious trouble if we started relying on all morphs being properly initialized ("properly" as in: having a definite link to some world unless destroyed).
How much more complex is it than adding owner _ WombWorld to Morph>>initialize? seems to make things simpler in that stuff is always initialized, except that initially it is to a world that isn't shown...
Anyway, regardless of what solution is chosen, it doesn't seem to me like something that's impossible to do in 3.7 or 3.8...
Ok, will pipe down and let the experts talk now...
Daniel
On Sat, Aug 16, 2003 at 08:38:08PM +0300, Daniel Vainsencher wrote:
Andreas Raab andreas.raab@gmx.de wrote:
Hi,
Andreas Raab andreas.raab@gmx.de wrote: I understand the problem, but you're implicit about the solution - do you mean that instead of todays remove we would change the Morphs parent to be the world?
No, what I'm saying is that the "owner" relationship should not be affected at all when you "remove" a morph.
Ah. It seems to me though we can keep the invariant you describe below (isParent(A,B) iff isSubmorph(B,A)) and still solve the problem. What do you think about fixing the issue the way I propose - every Morph always starts out with a parent (AstralWorld? WombWorld?), and can only change parents, but never remains orphaned. AFAICT, this would not change many implementation issues, but would require eventually changing the interfaces so that the remove would be replaced with #reParentTo: or something like it.
I think that Andreas is proposing doing away with this invariant, or making it one-directional:
(isSubmorph(B,A)) implies (isParent(A,B)), but not vice-versa. That way, a morph can always find its world by traversing up the owner chain, but morphs that have been "closed" will not be drawn, receive mouse events, etc.
Joshua
Secondly, there is a significant problem when creating new morphs. These days, new morphs are not initialized in a definitive context (e.g., when they are created their owner is nil) and one would need to provide appropriate initializations. Most places don't care about this at all and I would suspect that we'd get into serious trouble if we started relying on all morphs being properly initialized ("properly" as in: having a definite link to some world unless destroyed).
How much more complex is it than adding owner _ WombWorld to Morph>>initialize? seems to make things simpler in that stuff is always initialized, except that initially it is to a world that isn't shown...
Anyway, regardless of what solution is chosen, it doesn't seem to me like something that's impossible to do in 3.7 or 3.8...
Ok, will pipe down and let the experts talk now...
Daniel
I think that Andreas is proposing doing away with this invariant, or making it one-directional:
(isSubmorph(B,A)) implies (isParent(A,B)), but not vice-versa. That way, a morph can always find its world by traversing up the owner chain, but morphs that have been "closed" will not be drawn, receive mouse events, etc.
Yes, exactly. The last time this problem came up was in JIVE which actually shows the fundamental problem more clearly. When we are in 3D there really isn't any useful way of thinking about objects which are not in some space. Space is infinite and therefore if some guy isn't in some space then where the hell is he??? The only explanation for an object which is not in _some_ space is that it died away.
The same holds conceptually for Morphic if we just get a little off the restricted boundaries of some world on the screen. If we consider the world to be conceptually of infinite size, the same question arises with the same answer.
Cheers, - Andreas
No, what I'm saying is that the "owner" relationship should not be affected at all when you "remove" a morph.
Ah. It seems to me though we can keep the invariant you describe below (isParent(A,B) iff isSubmorph(B,A)) and still solve the problem. What do you think about fixing the issue the way I propose - every Morph always starts out with a parent (AstralWorld? WombWorld?), and can only change parents, but never remains orphaned.
I'm not sure if that AstralWorld would help too much here since typically, we require a "valid world" if we need to refer to it (and the AstralWorld wouldn't really be one). In this situation I would probably vote for the (implicit) ActiveWorld rather than some pseudo-world. It seems likely that this would be the better default here.
AFAICT, this would not change many implementation issues, but would require eventually changing the interfaces so that the remove would be replaced with #reParentTo: or something like it.
There's not much that would have to be done here - all it would mean is that sending #owner: would be a valid operation with the notion of removing the morph from its previous owner and setting the new owner.
Anyway, regardless of what solution is chosen, it doesn't seem to me like something that's impossible to do in 3.7 or 3.8...
I don't quite think so. This change would have tremendous implications on lots and lots of the code and without being able to deal with the efficiency issues during up-traversals you will find that Morphic can in fact be a whole lot slower than it is today ;-)
Cheers, - andreas
In Self you can open several windows, each with its own world. The handMorph is used to drag objects across the screen between these worlds, so it makes sense that something that has been picked up by the hand no longer belongs to the world over which it is hovering.
This probably is not the best way to do things in Squeak.
-- Jecel
On Sat, Aug 16, 2003 at 03:56:54PM -0300, Jecel Assumpcao Jr wrote:
In Self you can open several windows, each with its own world. The handMorph is used to drag objects across the screen between these worlds, so it makes sense that something that has been picked up by the hand no longer belongs to the world over which it is hovering.
What world does the hand belong to?
This probably is not the best way to do things in Squeak.
Why not?
Joshua
-- Jecel
In Self you can open several windows, each with its own world. The handMorph is used to drag objects across the screen between these worlds, so it makes sense that something that has been picked up by the hand no longer belongs to the world over which it is hovering.
Yes, this is one of the more interesting issues that come up in this regard. However, one of the key questions here is where exactly is a morph if it is being held by the hand while the hand is hovering "inbetween" those windows?
From my POV it makes sense to distinguish between different worlds here. For
example, while a morph is being held by the hand we can consider it in an "interim world" representing an infinite area (in which it may actually have to aquire its own "display" in order to be visible).
Note that something quite similar has been implemented in Croquet. When you drag a morph out of some embedded window (embedded in a 3D world) it will be transferred into the "root world" (which is the container of the 3D area) and when it enters another embedded world it will enter this particular world. Other mechanisms could be used (for example, keeping the object in 3D and simply make it "standalone") but the idea can be seen quite clearly.
One of the reasons why I am interested in having a "world" always associated with some morph is that when we do these "across worlds" operations there is a seriously interesting issue with respect to security and collaboration. Should I be able to drop a virus right onto your plate and have you deal with it? Probably not. So some identification of "where this guy belongs" seems very important here. The "world" it is associated with seems like a good boundary here. It would not prevent you from "importing" this guy if you want and trust it but knowing that this guy came from a "different" environment gives all sorts of interesting options.
Cheers, - Andreas
"Andreas Raab" andreas.raab@gmx.de wrote:
I don't quite think so. This change would have tremendous implications on lots and lots of the code and without being able to deal with the efficiency issues during up-traversals you will find that Morphic can in fact be a whole lot slower than it is today ;-)
I _really_ don't want to even imagine that. It's already annoying on anything less than 800MHz G3/PIII level. Please, let's see redesigns and improvements to make it faster on lower end machines.
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim Disc space, the final frontier!
I don't quite think so. This change would have tremendous implications on lots and lots of the code and without being able to deal with the efficiency issues during up-traversals you will find that Morphic can in fact be a whole lot slower than it is today ;-)
I _really_ don't want to even imagine that. It's already annoying on anything less than 800MHz G3/PIII level. Please, let's see redesigns and improvements to make it faster on lower end machines.
The trouble, of course, is that this isn't going to happen either unless you do some overall redesign of the architecture. And here, you'll be faced with a couple of hundred morph classes which will break in surprisingly new and unforeseen ways on you. One of the major issues with respect to Morphic deficiencies is that there are so few common bottlenecks (hot spots) which would be worthwhile optimzing for. In order to get some significant speed improvements you would have to introduce such bottlenecks first. And that's almost impossible with the amount of (often inconsistent and often enough plain broken) subclassing we see in Morphic.
Disc space, the final frontier!
I like this ;-)
Cheers, - Andreas
Hello, I was looking through the changelog on the latest CVS update and noticed with great rejoicing that the allmighty Ian is back! =))))
After correcting some conflicts with the update, I was able to run make in .../platforms/unix/config/ with the latest versions aclocal and autoconfig and it seemed to work.
I say seemed to because I was unable to test the resulting VM because my normal monitor blew up and I am stuck in console mode for the time being.
I bring this up because the solution to both my current difficulties, the guy with the X-less server and also a long-term solution to low-overhead squeaking is to complete work on the framebuffer driver.
Now that Ian is back, I will offer my meager services towards that project.
Also, I am eagerly awaiting the results of the SystemDictionary refactoring and cleanup because it mighmt be exactly what I need to implement a working prototype of my Sphere operating system. =))))
In general, keep up the great work. =)
Also, I am eagerly awaiting the results of the SystemDictionary refactoring and cleanup because it mighmt be exactly what I need to implement a working prototype of my Sphere operating system. =))))
Could you tell us what aspects are getting in your way?
Stef
Stephane Ducasse wrote:
Also, I am eagerly awaiting the results of the SystemDictionary refactoring and cleanup because it mighmt be exactly what I need to implement a working prototype of my Sphere operating system. =))))
Could you tell us what aspects are getting in your way?
1. general confusedness... -- nothing that isn't already beeing taken care of....
2. Poor object behavior... What I mean by that is System Dictionary seems to be designed to operate as an environment and its object behavior is quite poor -- a mere artifiact of it being written in smalltalk rather than a useful feature. This is even more the case with Display because there doesn't seem to be any way to use it with multi-window systems, remote X sessions, and systems with multiple physical displays...
I wish I could explain myself better. =P
I wish I could explain myself better. =P
I wish you would start doing something instead of waiting for someone to fix your problems for you. If you need multiple Displays I guess it would be a wise decision to look around for people and make proposals about how it should work, and then, by all means, implement it!
Otherwise you can spend the rest of your life waiting for something to happen or not.
Cheers, - Andreas
-----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] On Behalf Of Alan Grimes Sent: Sunday, August 17, 2003 7:44 PM To: The general-purpose Squeak developers list Subject: Re: Squeeek Leenooks Framebuffer. =)
Stephane Ducasse wrote:
Also, I am eagerly awaiting the results of the SystemDictionary refactoring and cleanup because it mighmt be exactly what
I need to
implement a working prototype of my Sphere operating system. =))))
Could you tell us what aspects are getting in your way?
- general confusedness... -- nothing that isn't already beeing taken
care of....
- Poor object behavior... What I mean by that is System Dictionary
seems to be designed to operate as an environment and its object behavior is quite poor -- a mere artifiact of it being written in smalltalk rather than a useful feature. This is even more the case with Display because there doesn't seem to be any way to use it with multi-window systems, remote X sessions, and systems with multiple physical displays...
I wish I could explain myself better. =P
-- "Nobody wants to say how this works. Mabye nobody knows." - The man page for XF86Config, One of the key config files behind the software driving the overwhealming majority of Linux desktops.
Ian the great has produced another masterpiece. His framebuffer driver is now roughly beta quality with only minor issues remaining. =)))
Being able to get into my immage again I started poking around....
running explorer on "Smalltalk keys" revealed that there are something like 1,700 symbols in the global dictionary! AIEEEEEEEE!! It is unclear wheather these are simply classes or pool dictionaries that should be reviewd. If these are classes then this complexity should be much abated if I manage to implement my Sphere Operating System. ;)
The explorer didn't seem to provide any way to inspect the values of these keys.... I am in over my head at this point and wouldn't even know where to begin implementing such functionality myself....
I also looked at the implementation of System Dictionary and went ahead and removed all the depreciated methods except two...
I am very pleased to see the complexity of these older classes being managed. =)
For 3.6 I would suggest that - all obsolete/depreciated methods be removed - All empty method categories be removed and the remainder alphebetized. - obsolete classes such as Array2D be removed.. - The global system dictionary be reviewed for obsolete variables. (If I understand what I'm talking about correctly).
Most of this is pretty trivial and I was able to do some of it with the immage I'm currently using... I am not sure how to submit the changes I have made for review and possible inclusion in the release.
On Wednesday 20 August 2003 03:11 pm, Alan Grimes wrote:
running explorer on "Smalltalk keys" revealed that there are something like 1,700 symbols in the global dictionary! AIEEEEEEEE!! It is unclear wheather these are simply classes or pool dictionaries that should be reviewd. If these are classes then this complexity should be much abated if I manage to implement my Sphere Operating System. ;)
The explorer didn't seem to provide any way to inspect the values of these keys.... I am in over my head at this point and wouldn't even know where to begin implementing such functionality myself....
Smalltalk keys size "print it =>" 1917 Smalltalk classNames size "print it =>" 1898 Smalltalk keys difference: Smalltalk classNames "print it =>" an IdentitySet(#Undeclared #Transcript #Smalltalk #ScheduledControllers #Sensor #ActiveEvent #References #SourceFiles #ActiveHand #MCMockClassPoolDictionary #SystemOrganization #World #ScriptingSystem #Processor #ImageImports #ActiveWorld #SRDebug #Display #TextConstants) ((Smalltalk keys difference: Smalltalk classNames) collect: [ :key | Smalltalk associationAt: key ifAbsent: [ ]]) asArray "explore it"
Also, we've had, since Squeak 1.2 in 1997,
Utilities inspectGlobals
which show you all the non-class globals, and their values.
Cheers,
-- Scott
At 12:20 PM -0700 8/20/03, Ned Konz wrote:
On Wednesday 20 August 2003 03:11 pm, Alan Grimes wrote:
running explorer on "Smalltalk keys" revealed that there are something like 1,700 symbols in the global dictionary! AIEEEEEEEE!! It is unclear wheather these are simply classes or pool dictionaries that should be reviewd. If these are classes then this complexity should be much abated if I manage to implement my Sphere Operating System. ;)
The explorer didn't seem to provide any way to inspect the values of these keys.... I am in over my head at this point and wouldn't even know where to begin implementing such functionality myself....
Smalltalk keys size "print it =>" 1917 Smalltalk classNames size "print it =>" 1898 Smalltalk keys difference: Smalltalk classNames "print it =>" an IdentitySet(#Undeclared #Transcript #Smalltalk #ScheduledControllers #Sensor #ActiveEvent #References #SourceFiles #ActiveHand #MCMockClassPoolDictionary #SystemOrganization #World #ScriptingSystem #Processor #ImageImports #ActiveWorld #SRDebug #Display #TextConstants) ((Smalltalk keys difference: Smalltalk classNames) collect: [ :key | Smalltalk associationAt: key ifAbsent: [ ]]) asArray "explore it"
Thanks scott I will check but it seems a good candidate to be moved in systemDictionary
This should be moved into System On Wednesday, August 20, 2003, at 11:21 PM, Scott Wallace wrote:
Also, we've had, since Squeak 1.2 in 1997,
Utilities inspectGlobals
which show you all the non-class globals, and their values.
Cheers,
-- Scott
At 12:20 PM -0700 8/20/03, Ned Konz wrote:
On Wednesday 20 August 2003 03:11 pm, Alan Grimes wrote:
running explorer on "Smalltalk keys" revealed that there are something like 1,700 symbols in the global dictionary! AIEEEEEEEE!! It is unclear wheather these are simply classes or pool dictionaries that should be reviewd. If these are classes then this complexity should be much abated if I manage to implement my Sphere Operating System. ;)
The explorer didn't seem to provide any way to inspect the values of these keys.... I am in over my head at this point and wouldn't even know where to begin implementing such functionality myself....
Smalltalk keys size "print it =>" 1917 Smalltalk classNames size "print it =>" 1898 Smalltalk keys difference: Smalltalk classNames "print it =>" an IdentitySet(#Undeclared #Transcript #Smalltalk #ScheduledControllers #Sensor #ActiveEvent #References #SourceFiles #ActiveHand #MCMockClassPoolDictionary #SystemOrganization #World #ScriptingSystem #Processor #ImageImports #ActiveWorld #SRDebug #Display #TextConstants) ((Smalltalk keys difference: Smalltalk classNames) collect: [ :key | Smalltalk associationAt: key ifAbsent: [ ]]) asArray "explore it"
om
/me is actually working on his Sphere OS idea ( stunned *ghasp* ).
The current #1 problem is this:
Many methods in Sphere's API require information from the thread itself to learn what permissions and contexts the thread has access to.
The interface object(s) are instantiated for all "Spheres" in the OS...
The current attempted design has a syscall object which receives messages. It then looks around the current context for an interface object which implements that message. If it fails, it sends the message up to its counterpart in the parent context.
This interface object must be able to query the calling THREAD, to learn its previous context...
Allowing threads to call interface objects with an explicit context parameter would be an exploitable vulnerability to spoofing.
I've created, for now, a "BogusProcess" class... The key being to be able to link a message all the way back to its process information block... Suggestions?
Problem #2 is debugging...
I'm attempting to code my first GUI... I would like to have some method browsers, container class views, a heavily modified CommandShell, and a number of varrious other buttons.
I've gotten it to open a SystemWindow in a fairly appropriate manner, (or so it would seem) the problem now is setting up a frame layout and then making sure all the panes and buttons communicate with each other in the desired fassion...
What tutorials/wiki pages should I go to in order to get my fix of information on the "extensions" based layout engine?
Hi alan
running explorer on "Smalltalk keys" revealed that there are something like 1,700 symbols in the global dictionary! AIEEEEEEEE!! It is unclear wheather these are simply classes or pool dictionaries that should be reviewd. If these are classes then this complexity should be much abated if I manage to implement my Sphere Operating System. ;)
If you do Object withAllSubclasses size you will see that Squeak has a lot of classes ;)
The explorer didn't seem to provide any way to inspect the values of these keys.... I am in over my head at this point and wouldn't even know where to begin implementing such functionality myself....
I also looked at the implementation of System Dictionary and went ahead and removed all the depreciated methods except two...
I am very pleased to see the complexity of these older classes being managed. =)
For 3.6 I would suggest that
- all obsolete/depreciated methods be removed
They will but not in 3.6 else people will have headaches to find why their system is breaking. Deprecated methods cost nothing and help maintainers so no problem with them
- All empty method categories be removed and the remainder
alphebetized.
- obsolete classes such as Array2D be removed..
Interesting
- The global system dictionary be reviewed for obsolete variables. (If
I understand what I'm talking about correctly).
Which one? I'm curing SystemDictionary and created a new class SmalltalkImage that will have all these variables.
Most of this is pretty trivial and I was able to do some of it with the immage I'm currently using... I am not sure how to submit the changes I have made for review and possible inclusion in the release.
Decompose what you are doing in ***small*** well identified changeset with comments. Look at how we did the KCP items http://minnow.cc.gatech.edu/squeak/3254
Send them into the list we will have a look at them.
Then have a look at the KCP page.
Stef
-- "Nobody wants to say how this works. Mabye nobody knows." - The man page for XF86Config, One of the key config files behind the software driving the overwhealming majority of Linux desktops.
Stephane Ducasse wrote:
Hi alan
For 3.6 I would suggest that
- all obsolete/depreciated methods be removed
They will but not in 3.6 else people will have headaches to find why their system is breaking. Deprecated methods cost nothing and help maintainers so no problem with them
Right. The idea is that we will remove all the deprecated methods at the beginning of 3.7alpha, this is a pretty standard practice. The idea is that the methods will be deprecated but still working (with the warnings) for one release (3.6 final) but will be gone in 3.7.
- Doug
Hello, I'm having trouble with my leenooks VM, It totally messes up whenever it has to deal with any kind of FP stuff. (I have seen many FP related failures in every squeak configuration I have tried).
Today, I took a fresh 3.6 beta immage and attempted to use "upgrade to 3.6 full" and the thing blew up when it was trying to do something with some class called "fisheyemorph" or something similar... Apparently it was attempting to truncate what it thought was a float number but the number had been read as "not a number" (NaN)...
Apparently some critical setting regarding x86 FP stuff is not being initialized by the current configuration scripts.
What information do you need to see from me?
Alan Grimes wrote:
Hello, I'm having trouble with my leenooks VM, It totally messes up whenever it has to deal with any kind of FP stuff. (I have seen many FP related failures in every squeak configuration I have tried).
Today, I took a fresh 3.6 beta immage and attempted to use "upgrade to 3.6 full" and the thing blew up when it was trying to do something with some class called "fisheyemorph" or something similar... Apparently it was attempting to truncate what it thought was a float number but the number had been read as "not a number" (NaN)...
Apparently some critical setting regarding x86 FP stuff is not being initialized by the current configuration scripts.
What information do you need to see from me?
Do you see an error within Squeak? (with the usual pink debugger window?) If so, you can select "mail out bug report" from the pop-up menu in the stack pane of the debugger window to send the error stack to the list, which'll be helpful.
Otherwise, if your VM is crashing, that's a different story.
- Doug
Is this a problem with a VM you are hacking, one compiled untouched source code, or one you have downloaded from somewhere?
Joshua
On Fri, Aug 29, 2003 at 05:58:33PM -0700, Alan Grimes wrote:
Hello, I'm having trouble with my leenooks VM, It totally messes up whenever it has to deal with any kind of FP stuff. (I have seen many FP related failures in every squeak configuration I have tried).
Today, I took a fresh 3.6 beta immage and attempted to use "upgrade to 3.6 full" and the thing blew up when it was trying to do something with some class called "fisheyemorph" or something similar... Apparently it was attempting to truncate what it thought was a float number but the number had been read as "not a number" (NaN)...
Apparently some critical setting regarding x86 FP stuff is not being initialized by the current configuration scripts.
What information do you need to see from me?
-- "Nobody wants to say how this works. Mabye nobody knows." - The man page for XF86Config, One of the key config files behind the software driving the overwhealming majority of Linux desktops.
Joshua 'Schwa' Gargus wrote:
Is this a problem with a VM you are hacking, one compiled untouched source code, or one you have downloaded from somewhere?
Compiled untouched from the CVS tree + Ian's framebuffer driver. The details were included in the bug report I sent to the list about an hour ago.
Hey Alan,
Did you ever resolve this issue? The reason I ask is that I just love each and every Squeaker that much!
Well, that and because I'm now having the same problem. Here is a snippet that is pretty close to the root of the problem:
#(1 3 5) asFloatArray += 2.5 ==> a FloatArray(1.0 3.0 5.0)
Your problem with FishEyeMorph was caused by using += to add to a FloatArray. When this didn't work, the array was left filled with zeros. Then, when 1.0 was divided by the array, the result was an array filled with Infinities. And so on...
I haven't gotten too far with debugging this. One thing I did do was take the external FloatArrayPlugin that I compiled with the 3.5 sources (works fine) and tried it with my newly compiled 3.6 VM (no longer works fine). The plugin is being loaded fine; that's as far as I've gotten.
I should mention that I compiled the 3.6 VM with a slightly newer GCC (3.3.2) than I did for the 3.5 VM (I don't remember which version that was, I just let Debian do the upgrading).
Hopefully we can get to the bottom of this, Joshua
On Fri, Aug 29, 2003 at 08:12:08PM -0700, Alan Grimes wrote:
Joshua 'Schwa' Gargus wrote:
Is this a problem with a VM you are hacking, one compiled untouched source code, or one you have downloaded from somewhere?
Compiled untouched from the CVS tree + Ian's framebuffer driver. The details were included in the bug report I sent to the list about an hour ago.
-- "Nobody wants to say how this works. Mabye nobody knows." - The man page for XF86Config, One of the key config files behind the software driving the overwhealming majority of Linux desktops.
On Friday 05 September 2003 07:27 pm, Joshua 'Schwa' Gargus wrote:
Well, that and because I'm now having the same problem. Here is a snippet that is pretty close to the root of the problem:
#(1 3 5) asFloatArray += 2.5 ==> a FloatArray(1.0 3.0 5.0)
On my Linux VM (compiled with GCC v3.3):
#(1 3 5) asFloatArray += 2.5 --> a FloatArray(3.5 5.5 7.5)
Have you tried making the FloatArrayPlugin internal?
Smalltalk listLoadedModules -> #('LargeIntegers v1.2 3 September 2003 (i)' 'B2DPlugin 3 September 2003 (i)' 'Matrix2x3Plugin 3 September 2003 (i)' 'FloatArrayPlugin 3 September 2003 (i)' 'BitBltPlugin 3 September 2003 (i)' 'SecurityPlugin 3 September 2003 (i)' 'FilePlugin 3 September 2003 (i)' 'MiscPrimitivePlugin 3 September 2003 (i)')
On Fri, Sep 05, 2003 at 09:28:51PM -0700, Ned Konz wrote:
On Friday 05 September 2003 07:27 pm, Joshua 'Schwa' Gargus wrote:
Well, that and because I'm now having the same problem. Here is a snippet that is pretty close to the root of the problem:
#(1 3 5) asFloatArray += 2.5 ==> a FloatArray(1.0 3.0 5.0)
On my Linux VM (compiled with GCC v3.3):
#(1 3 5) asFloatArray += 2.5 --> a FloatArray(3.5 5.5 7.5)
(pulls out calculator) Yes, that looks right :-)
Have you tried making the FloatArrayPlugin internal?
No, I'll try that next.
Other things I've tried: I verified that the 'fetchFloatAtinto' macro being used is the first one (the one that does swapping for little-endian architectures). However, the value being fetched is 0.0 for some reason that I haven't yet figured out.
Internal FloatArrayPlugin, then bed!
Thanks for the help, Joshua
Smalltalk listLoadedModules -> #('LargeIntegers v1.2 3 September 2003 (i)' 'B2DPlugin 3 September 2003 (i)' 'Matrix2x3Plugin 3 September 2003 (i)' 'FloatArrayPlugin 3 September 2003 (i)' 'BitBltPlugin 3 September 2003 (i)' 'SecurityPlugin 3 September 2003 (i)' 'FilePlugin 3 September 2003 (i)' 'MiscPrimitivePlugin 3 September 2003 (i)')
-- Ned Konz http://bike-nomad.com GPG key ID: BEEA7EFE
On Fri, Sep 05, 2003 at 09:28:51PM -0700, Ned Konz wrote:
On Friday 05 September 2003 07:27 pm, Joshua 'Schwa' Gargus wrote:
Well, that and because I'm now having the same problem. Here is a snippet that is pretty close to the root of the problem:
#(1 3 5) asFloatArray += 2.5 ==> a FloatArray(1.0 3.0 5.0)
On my Linux VM (compiled with GCC v3.3):
#(1 3 5) asFloatArray += 2.5 --> a FloatArray(3.5 5.5 7.5)
Have you tried making the FloatArrayPlugin internal?
with internal plugin:
#(1 3 5) asFloatArray += 2.5 ==> a FloatArray(6.0979456e7 6.097946e7 6.097946e7)
Woo-hoo. I don't pretend to be awake enough to consider the implications.
'till tomorrow, Joshua
Smalltalk listLoadedModules -> #('LargeIntegers v1.2 3 September 2003 (i)' 'B2DPlugin 3 September 2003 (i)' 'Matrix2x3Plugin 3 September 2003 (i)' 'FloatArrayPlugin 3 September 2003 (i)' 'BitBltPlugin 3 September 2003 (i)' 'SecurityPlugin 3 September 2003 (i)' 'FilePlugin 3 September 2003 (i)' 'MiscPrimitivePlugin 3 September 2003 (i)')
-- Ned Konz http://bike-nomad.com GPG key ID: BEEA7EFE
On Fri, 5 Sep 2003, Joshua 'Schwa' Gargus wrote:
Did you ever resolve this issue? I haven't gotten too far with debugging this.
I just tried with the latest Debian compiler on 386.
The problem is in the interpreter, not in the plugin. And it looks like a compiler bug.
double stackFloatValue(int offset) is the culprit. Inserting
printf("result == %lf\n", result);
just before the return causes it to start working (so it's definitely a compiler problem). Declaring result as static causes the function to return the value fetched from the Float on the previous call (i.e., the result is out of sync by 1 function call). Conclusion: fetchFloatAtinto() is working but the compiler is loading the double return value from result before actually doing the fetch.
You should switch to a different compiler until it's fixed (and file a report to gcc-bugs, if you'd like it to be fixed any time soon ;).
If that's not an option then one possible expedient hack is to insert an empty asm statement [*] before the return from stackFloatValue() like this
fetchFloatAtinto(floatPointer + BaseHeaderSize, result); asm(""); return result;
and recompile your VM. (But there is no telling how many other float functions are similarly afflicted, so I don't recommend this as a solution.)
Ian
[*] This works because the insn scheduler will not move loads across a basic block boundary, and it considers any asm() statement -- even an empty one -- to be a boundary.
Thanks for both this catch, and the compilation fix. I'll bug the gcc people about it tomorrow.
Joshua
On Sat, Sep 06, 2003 at 07:04:30AM +0200, Ian Piumarta wrote:
On Fri, 5 Sep 2003, Joshua 'Schwa' Gargus wrote:
Did you ever resolve this issue? I haven't gotten too far with debugging this.
I just tried with the latest Debian compiler on 386.
The problem is in the interpreter, not in the plugin. And it looks like a compiler bug.
double stackFloatValue(int offset) is the culprit. Inserting
printf("result == %lf\n", result);
just before the return causes it to start working (so it's definitely a compiler problem). Declaring result as static causes the function to return the value fetched from the Float on the previous call (i.e., the result is out of sync by 1 function call). Conclusion: fetchFloatAtinto() is working but the compiler is loading the double return value from result before actually doing the fetch.
You should switch to a different compiler until it's fixed (and file a report to gcc-bugs, if you'd like it to be fixed any time soon ;).
If that's not an option then one possible expedient hack is to insert an empty asm statement [*] before the return from stackFloatValue() like this
fetchFloatAtinto(floatPointer + BaseHeaderSize, result); asm(""); return result;
and recompile your VM. (But there is no telling how many other float functions are similarly afflicted, so I don't recommend this as a solution.)
Ian
[*] This works because the insn scheduler will not move loads across a basic block boundary, and it considers any asm() statement -- even an empty one -- to be a boundary.
Building with gcc-3.2 fixed the problem. Thanks.
What should a bug-report to gcc-bugs look like? Should I include the incorrect assembly code? Should I create a minimal program that exhibits this behavior? I'm not completely sure how to go about doing the former, and don't know if the latter is feasible. Or should I just describe the symptom?
Thanks, Joshua
On Sat, Sep 06, 2003 at 07:04:30AM +0200, Ian Piumarta wrote:
On Fri, 5 Sep 2003, Joshua 'Schwa' Gargus wrote:
Did you ever resolve this issue? I haven't gotten too far with debugging this.
I just tried with the latest Debian compiler on 386.
The problem is in the interpreter, not in the plugin. And it looks like a compiler bug.
double stackFloatValue(int offset) is the culprit. Inserting
printf("result == %lf\n", result);
just before the return causes it to start working (so it's definitely a compiler problem). Declaring result as static causes the function to return the value fetched from the Float on the previous call (i.e., the result is out of sync by 1 function call). Conclusion: fetchFloatAtinto() is working but the compiler is loading the double return value from result before actually doing the fetch.
You should switch to a different compiler until it's fixed (and file a report to gcc-bugs, if you'd like it to be fixed any time soon ;).
If that's not an option then one possible expedient hack is to insert an empty asm statement [*] before the return from stackFloatValue() like this
fetchFloatAtinto(floatPointer + BaseHeaderSize, result); asm(""); return result;
and recompile your VM. (But there is no telling how many other float functions are similarly afflicted, so I don't recommend this as a solution.)
Ian
[*] This works because the insn scheduler will not move loads across a basic block boundary, and it considers any asm() statement -- even an empty one -- to be a boundary.
Hi,
What should a bug-report to gcc-bugs look like?
If you run the program "gccbug" it should lead you through the steps. (There's a man page too.)
Should I include the incorrect assembly code?
No.
Should I create a minimal program that exhibits this behavior?
Yes, if at all possible, preferably without any includes.
don't know if the latter is feasible.
I'd cut and paste the fetchFloatAtinto macro into a new .c file, then paste the offending function in there, then write a tiny main() that reproduces the problam. You might have to put different parts in separate files to avoid the optimiser optimising too much.
Or should I just describe the symptom?
That too.
If you have to include the entire file, run it through the preprocessor first. Delete gnu-interp.o, cd bld/vm, make gnu-interp.o then copy the compiler command and run it again replacing "-o gnu-interp.o" with "-E -o gnu-interp.i". gnu-interp.i is the file they'd like to see (assuming you can't write a small test case).
(I could try to make a small test-case program if you like.)
Regards, Ian
On Sat, 6 Sep 2003, Ian Piumarta wrote:
(I could try to make a small test-case program if you like.)
Attached.
If you don't want to check the pending bugs on the gcc site and file the PR only if it's not already there, then I'm willing to do it.
Ian
/* compile-command: gcc -O2 -fomit-frame-pointer -o fpbug fpbug.c * gcc -O2 -fomit-frame-pointer -o fpbug fpbug.c -DBUGFIX=1 */
#define BaseHeaderSize 4
#define longAt(i) (*((int *) (i)))
/* #undef WORDS_BIGENDIAN */ /* #undef DOUBLE_WORD_ALIGNMENT */ #define DOUBLE_WORD_ORDER 1
#if defined(DOUBLE_WORD_ALIGNMENT) || defined(DOUBLE_WORD_ORDER) # ifdef DOUBLE_WORD_ORDER /* word-based copy with swapping for non-PowerPC order */ # define storeFloatAtfrom(i, floatVarName) \ *((int *) (i) + 0) = *((int *) &(floatVarName) + 1); \ *((int *) (i) + 1) = *((int *) &(floatVarName) + 0); # define fetchFloatAtinto(i, floatVarName) \ *((int *) &(floatVarName) + 0) = *((int *) (i) + 1); \ *((int *) &(floatVarName) + 1) = *((int *) (i) + 0); # else /*!DOUBLE_WORD_ORDER*/ /* word-based copy for machines with alignment restrictions */ # define storeFloatAtfrom(i, floatVarName) \ *((int *) (i) + 0) = *((int *) &(floatVarName) + 0); \ *((int *) (i) + 1) = *((int *) &(floatVarName) + 1); # define fetchFloatAtinto(i, floatVarName) \ *((int *) &(floatVarName) + 0) = *((int *) (i) + 0); \ *((int *) &(floatVarName) + 1) = *((int *) (i) + 1); # endif /*!DOUBLE_WORD_ORDER*/ #else /*!(DOUBLE_WORD_ORDER||DOUBLE_WORD_ALIGNMENT)*/ /* for machines that allow doubles to be on any word boundary */ # define storeFloatAtfrom(i, floatVarName) \ *((double *) (i)) = (floatVarName); # define fetchFloatAtinto(i, floatVarName) \ (floatVarName) = *((double *) (i)); #endif
struct foo { int stackPointer; } fum; struct foo *foo= &fum;
double stackFloatValue(int offset) { register struct foo * foo = &fum; double result; int floatPointer; floatPointer = longAt(foo->stackPointer - (offset * 4)); fetchFloatAtinto(floatPointer + BaseHeaderSize, result); #ifdef BUGFIX asm(""); #endif return result; }
struct Float { unsigned int baseHeader; unsigned int bytes[2]; };
static struct Float myFloat; static int stack[2];
int main() { double result;
myFloat.bytes[0]= 0x400921fb; myFloat.bytes[1]= 0x54442d02;
stack[0]= (int)&myFloat; fum.stackPointer= (int)(&stack[1]);
result= stackFloatValue(1); printf("got %lf\n", result); result= stackFloatValue(1); printf("got %lf\n", result);
return 0; }
Joshua 'Schwa' Gargus wrote:
Building with gcc-3.2 fixed the problem. Thanks.
Interesting...
I was using 3.2.2 (I think) before and it was broken....
So it should be possible, though not necessarily practical, to isolate the change which introduced the bug.
In the meantime I totally hosed my system by doing a bunch of badly misguided re-compiles of critical system components. [with the apparently broken gcc 3.3.1...]
BTW, there are a number of version conflicts between the current cvs sources, ian's sources, and the latest public immage which (as of this morning) made compilation of gnu-interp.c impossible... From the morning list trafic, it sounds as if it is already being taken care of...
On Sat, Sep 06, 2003 at 03:09:43PM -0700, Alan Grimes wrote:
Joshua 'Schwa' Gargus wrote:
Building with gcc-3.2 fixed the problem. Thanks.
Interesting...
I was using 3.2.2 (I think) before and it was broken....
Mine is 3.2.3. However, Ian wrote a small C program for the purpose of demonstrating the bug for the GCC developers, and gcc-3.2.3 still produced the wrong output, despite apparently compiling a working VM. If I notice any further problems, I'm back to gcc-2.95, which didn't exhibit the bug.
Joshua
So it should be possible, though not necessarily practical, to isolate the change which introduced the bug.
In the meantime I totally hosed my system by doing a bunch of badly misguided re-compiles of critical system components. [with the apparently broken gcc 3.3.1...]
BTW, there are a number of version conflicts between the current cvs sources, ian's sources, and the latest public immage which (as of this morning) made compilation of gnu-interp.c impossible... From the morning list trafic, it sounds as if it is already being taken care of...
-- "Nobody wants to say how this works. Mabye nobody knows." - The man page for XF86Config, One of the key config files behind the software driving the overwhealming majority of Linux desktops.
squeak-dev@lists.squeakfoundation.org