Hi folks: I am trying to understand ImageSegment methods like activeClasses, swapOutInactiveClasses, discoverActiveClasses among others. One of the comments of those methods says:
"NOTE: discoverActiveClasses uses Squeak's ability to detect and recover from faults due to a nil method dictionary. It staches the method dict in with the organization during the time when discovery is in progress (Gag me with a spoon). This is why the faults need to be cleared promptly before resuming normal work with the system. It is also important that classes *do not* refer directly to their method dictionary, but only via the accessor message." So, it seems to HACK (it forces a fault) this MD fault recover to discover inactive classes and other things. Ok, forget that hack for a moment. What questions is, what are these faults? Why a method dictionary can be in nil ? How is this produced ? And how is it fixed? I saw for example this: Behaviour>>methodDict methodDict == nil ifTrue: [self recoverFromMDFaultWithTrace]. ^ methodDict But again...how can that be nil ??? Thank you very much. Marian _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
> Hi folks: I am trying to understand ImageSegment methods like activeClasses, swapOutInactiveClasses, discoverActiveClasses among others. One of the comments of those methods says:
> > "NOTE: discoverActiveClasses uses Squeak's ability to detect and recover from faults due to a nil method dictionary. It staches the method dict in with the organization during the time when discovery is in progress (Gag me with a spoon). This is why the faults need to be cleared promptly before resuming normal work with the system. It is also important that classes *do not* refer directly to their method dictionary, but only via the accessor message." > > So, it seems to HACK (it forces a fault) this MD fault recover to discover inactive classes and other things. Ok, forget that hack for a moment. > > What questions is, what are these faults? Why a method dictionary can be in nil ? How is this produced ? And how is it fixed? > > I saw for example this: > > Behaviour>>methodDict > methodDict == nil ifTrue: [self recoverFromMDFaultWithTrace]. > ^ methodDict > > > But again...how can that be nil ??? VM code put it to nil. The idea is that the methodDict is stored in the class or method cat and nil is put in place of the methodDict. Then when the VM detects that the methodDict is nil then it copies the methodDict stored into the category This way you know which class has been used during your interaction. We tried to use it with mathieu but we often got all the classes back on place. And it crashed a lot :) Stef > > Thank you very much. > > Marian > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Wed, Dec 23, 2009 at 2:16 PM, Stéphane Ducasse <[hidden email]> wrote:
Thanks Stef. After a discussion with Andreas in Squeak-dev mailing list, I wanted to ask you too. I could perfectly saw that when trying to discover used classes. I also saw the method ClassDescription>> induceMDFault. However, I still have this question: Forget about discovering classes, could be possible that for a certain situation the VM puts a nil to a method directory or always that happens this is done with that intention, through the message induceMDFault ? If it is always through induceMDFault the only sender is to discover used classes with ImageSegment. So...it is used ONLY in that? The possibility of using #instVarAt:put: accidentally is rejected because the recover will search the methodDict in the category (organization). So, if I just set a nil to the methodDict using #instVarAt:put: but I don't "backup" the methodDic in the category, the recover won't work. thanks Mariano ps: yes, I am thinking in clean up all this class discovery to another place than ImageSegment what I wonder if those messages for MD faults should be put off too. Stef _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Mariano Martinez Peck
Mariano Martinez Peck <marianopeck@...> writes:
> So, it seems to HACK (it forces a fault) this MD fault recover to discover > inactive classes and other things. Ok, forget that hack for a moment. > > What questions is, what are these faults? Why a method dictionary can be in > nil ? How is this produced ? And how is it fixed? > > I saw for example this: > > Behaviour>>methodDict > methodDict == nil ifTrue: [self recoverFromMDFaultWithTrace]. > ^ methodDict > > But again...how can that be nil ??? I guess your missing link is ProtoObject >> #cannotInterpret: which is executed by the VM whenever you try to send a message to an object whose class does not have a method dictionary. Further methods that you should look at are ClassDescription >> #induceMDFault ClassDescription >> #recoverFromMDFault ClassDescription >> #recoverFromMDFaultWithTrace and their senders. Except for the call to #cannotInterpret by the VM, all the rest is done in the image (stef got that wrong) and you can go and read the code. All in all, it is a highly sophisticated (read *ugly*) hack and I'd say an evil use of superpowers. --AA _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Ok this is in the image I did not remember (getting old) :) but the vm pay attention
not to crash totally when you put nil in a methodDict. Now what I know is that a while back when we activate Smalltalk at: #MDFaultDict put: Dictionary new. We kind of either crashed or got all the classes of the system in. I have the impression that this is just a hack and I would remove it from the system because we can do with MW or reflectivity (even if we probably cannot trace the tracing code). Also the granularity is really the class so as soon as one method is invoked you get all the class back. So with mathieu we simply something could not understand why all the classes would be touched may be browser was scanning all the image. No idea. but at the end it was not useful. Stef On Dec 23, 2009, at 4:51 PM, Adrian Kuhn wrote: > Mariano Martinez Peck <marianopeck@...> writes: > >> So, it seems to HACK (it forces a fault) this MD fault recover to discover >> inactive classes and other things. Ok, forget that hack for a moment. >> >> What questions is, what are these faults? Why a method dictionary can be in >> nil ? How is this produced ? And how is it fixed? >> >> I saw for example this: >> >> Behaviour>>methodDict >> methodDict == nil ifTrue: [self recoverFromMDFaultWithTrace]. >> ^ methodDict >> >> But again...how can that be nil ??? > > I guess your missing link is > > ProtoObject >> #cannotInterpret: > > which is executed by the VM whenever you try to send a message to an object > whose class does not have a method dictionary. Further methods that you should > look at are > > ClassDescription >> #induceMDFault > ClassDescription >> #recoverFromMDFault > ClassDescription >> #recoverFromMDFaultWithTrace > > and their senders. Except for the call to #cannotInterpret by the VM, all the > rest is done in the image (stef got that wrong) and you can go and read the > code. All in all, it is a highly sophisticated (read *ugly*) hack and I'd say > an evil use of superpowers. > > --AA > > > > > > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Adrian: Thanks, indeed cannotInterpret: was what I was looking for :)
On Wed, Dec 23, 2009 at 5:19 PM, Stéphane Ducasse <[hidden email]> wrote: Ok this is in the image I did not remember (getting old) :) but the vm pay attention ok Now what I know is that a while back when we activate What's MW ? Now...the question is, suppose I remove all the methods like discoverUnusedCLasses, activeClasses, and so on, can I remove also the methods induceMDFault, recoverFromMDFault, etc ??? Or there are other users? As I understood, there aren't. In addition, I don't see the relation between cannotInterpret: and those methods, because cannotInerpret: does not call this methods to recover. Also the granularity is really the class so as soon as one method is invoked you get all the class back. Yes, I noticed that too. Is very probable that messages very general that are used a lot will bring the class again. So with mathieu we simply something could not understand why all the classes would be touched That's the idea of the tracer. WIth this tracer you *should* be able to see the messages chain that makes you bring the class (why it was used). But I don't know if this stuff is working, as you said.
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
> What's MW ?
MethodWrapper. But you cannot wrap the complete system like do: (if I remember correctly). > Yes, I noticed that too. Is very probable that messages very general that are used a lot will bring the class again. Yes the problem is to identify them. We tried a bit not too much with mathieu but was not obvious > That's the idea of the tracer. WIth this tracer you *should* be able to see the messages chain that makes you bring the class (why it was used). But I don't know if this stuff is working, as you said. which tracer? What I suggest: - create a new category in the class and move all the methods that could be removed. Tag them as deprecated. - in imageSegments just clean :) Stef _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Thu, Dec 24, 2009 at 11:46 AM, Stéphane Ducasse <[hidden email]> wrote: > What's MW ? ok
yes haha
Suppose you evaluate this steps: Smalltalk at: #MDFaultDict put: Dictionary new. ImageSegment discoverActiveClasses .... do something here, browse, whatever .... ImageSegment activeClasses Here, you can change activeClasses to use recoverFromMDFaultWithTrace instead of recoverFromMDFault and with this you can see who used that class. It is stored in Smalltalk at: #MDFaultDict Ok...at least that is what I understood, but as this is not working, I am not sure. What I suggest: - in imageSegments just clean :) Ok. Perfect. Cheers Mariano Stef _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
> Suppose you evaluate this steps: > > Smalltalk at: #MDFaultDict put: Dictionary new. > ImageSegment discoverActiveClasses > > .... do something here, browse, whatever .... > > ImageSegment activeClasses > > Here, you can change activeClasses to use recoverFromMDFaultWithTrace instead of recoverFromMDFault > and with this you can see who used that class. It is stored in Smalltalk at: #MDFaultDict Ok good to know that it is working. At some point doing that would just crash. > Ok...at least that is what I understood, but as this is not working, I am not sure. This is correct. > What I suggest: > - create a new category in the class and move all the methods that could be removed. Tag them as deprecated. do not deprecated them since this is working. :) > - in imageSegments just clean :) What is the link with imageSegment? > > > Ok. Perfect. > > Cheers > > Mariano > > Stef > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Thu, Dec 24, 2009 at 12:09 PM, Stéphane Ducasse <[hidden email]> wrote:
Sorry I am lazy, I will copy paste a piece of a .tex \section{Discovering used and unused classes} There is some work that it is quite related to ImageSegment and it is used to discover used and unused classes. There is a possibility to force a MethodDictionary fault with the message {\em ClassDescription>>induceMDFault}. This method copies the {\em methodDict} in the {\em organization} slot. Actually, it creates an Array with the {\em methodDict} and the {\em organization} and set it in the {\em organization} slot. Finally, it sets a {\em nil} to the {\em methodDict} instance variable. After this is done, when that class is used and the {\em methodDict} is asked\,---\,it is very important to acces the {\em methodDict} using the getter\,---\, it checks whether it is nil or not. If it is nil, it will search for that {\em methodDict} in the Array of the {\em organizaction} and it will then copy it to the {\em methodDict} instance variable. Taking that explanation in mind, we can follow this three steps: \begin{enumerate} \item Send the message {\em ImageSegment>>discoverActiveClasses} which forces a MethodDictionary fault in all classes. Yes! It sends the message {\em induceMDFault} to all classes except classes like Array Object Class Message MethodDictionary. After this, all classes but those ones, will have the {\em methodDict} with {\em nil}. \item Do a few things, use the system for a while. Maybe even save and resume the image. \item Now, it is easy. All classes that still have a nil in the {\em mehodDict} is because they were not used, and those who have something different from {\em nil} is because they were. With the message {\em ImageSegment>>activeClasses} you can restore all remaining MethodDictionary faults and return the active classes. And with the message {\em ImageSegment>>swapOutInactiveClasses} you can make up segments by grouping unused classes by system category and write them to disk. A very important thing is that if you send the message {\em discoverActiveClasses} you must then have to send the message {\em activeClasses} or {\em swapOutInactiveClasses} because otherwise you will have a lot of classes with the {\em methodDict} in {\em nil}. \end{enumerate} is it clear ?
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
> Taking that explanation in mind, we can follow this three steps:
> > \begin{enumerate} > \item Send the message {\em ImageSegment>>discoverActiveClasses} which forces a MethodDictionary fault in all classes. Yes! It sends the message {\em induceMDFault} to all classes except classes like Array Object Class Message MethodDictionary. After this, all classes but those ones, will have the {\em methodDict} with {\em nil}. > \item Do a few things, use the system for a while. Maybe even save and resume the image. > \item Now, it is easy. All classes that still have a nil in the {\em mehodDict} is because they were not used, and those who have something different from {\em nil} is because they were. With the message {\em ImageSegment>>activeClasses} you can restore all remaining MethodDictionary faults and return the active classes. And with the message {\em ImageSegment>>swapOutInactiveClasses} you can make up segments by grouping unused classes by system category and write them to disk. > > A very important thing is that if you send the message {\em discoverActiveClasses} you must then have to send the message {\em activeClasses} or {\em swapOutInactiveClasses} because otherwise you will have a lot of classes with the {\em methodDict} in {\em nil}. > > \end{enumerate} > > > is it clear ? Yes. So may be you should create an ImageSegment package and put the faultDescription as class extensions to this package. Did you try to see what are the inactive classes you get after a full coding sesssion with loading and saving code? _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Thu, Dec 24, 2009 at 12:33 PM, Stéphane Ducasse <[hidden email]> wrote:
Yes, but the results is all classes are used, which of course is wrong. But...investigating a bit, the problem is here. Look this example: ByteString induceMDFault. self assert: (ByteString instVarNamed: 'methodDict') isNil That assert returns a failure!!! how is that posssible ? if the induceMDFault is setting methodDict nil . weird...
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
2009/12/24 Mariano Martinez Peck <[hidden email]>:
> > > On Thu, Dec 24, 2009 at 12:33 PM, Stéphane Ducasse > <[hidden email]> wrote: >> >> > Taking that explanation in mind, we can follow this three steps: >> > >> > \begin{enumerate} >> > \item Send the message {\em ImageSegment>>discoverActiveClasses} which >> > forces a MethodDictionary fault in all classes. Yes! It sends the message >> > {\em induceMDFault} to all classes except classes like Array Object Class >> > Message MethodDictionary. After this, all classes but those ones, will have >> > the {\em methodDict} with {\em nil}. >> > \item Do a few things, use the system for a while. Maybe even save and >> > resume the image. >> > \item Now, it is easy. All classes that still have a nil in the {\em >> > mehodDict} is because they were not used, and those who have something >> > different from {\em nil} is because they were. With the message {\em >> > ImageSegment>>activeClasses} you can restore all remaining MethodDictionary >> > faults and return the active classes. And with the message {\em >> > ImageSegment>>swapOutInactiveClasses} you can make up segments by grouping >> > unused classes by system category and write them to disk. >> > >> > A very important thing is that if you send the message {\em >> > discoverActiveClasses} you must then have to send the message {\em >> > activeClasses} or {\em swapOutInactiveClasses} because otherwise you will >> > have a lot of classes with the {\em methodDict} in {\em nil}. >> > >> > \end{enumerate} >> > >> > >> > is it clear ? >> >> Yes. >> So may be you should create an ImageSegment package and put the >> faultDescription as class extensions to this package. >> >> Did you try to see what are the inactive classes you get after a full >> coding sesssion with loading and saving code? >> > > Yes, but the results is all classes are used, which of course is wrong. > But...investigating a bit, the problem is here. Look this example: > > ByteString induceMDFault. > self assert: (ByteString instVarNamed: 'methodDict') isNil > > That assert returns a failure!!! how is that posssible ? if the > induceMDFault is setting methodDict nil . > > weird... > > Just a guess, I did not look at code, but couldn't it be that instVarNamed: rely on String>>#= and thus resurrect the methodDictionary ? Maybe you should write: self should: [ByteString instVarNamed: 'methodDict'] raise: MDFault > > >> >> _______________________________________________ >> Pharo-project mailing list >> [hidden email] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Thu, Dec 24, 2009 at 3:03 PM, Nicolas Cellier <[hidden email]> wrote: 2009/12/24 Mariano Martinez Peck <[hidden email]>: Thanks Nicolas. Yes, something like that was happening. I don't know why I was so idiot and took ByteString as an example haha. Now I did some test. Just evaluating this (without any work on an image) ImageSegment discoverActiveClasses. ImageSegment activeClasses. You get 227 classes used (over 3332 in total) I will let this stuff running and work a couple of hours in a normal work and see how much classes do I use. Cheers, Mariano
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Stéphane Ducasse
On Thu, Dec 24, 2009 at 12:33 PM, Stéphane Ducasse <[hidden email]> wrote:
Yes, as expected, it doesn't work. Just looking for implementors for example, puts all classes as active (which make sense).
_______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Mariano Martinez Peck
> You get 227 classes used (over 3332 in total)
these ones are nice to know Now just open a Morph to see or an inspector. Or typing some code Stef _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
On Thu, Dec 24, 2009 at 4:26 PM, Stéphane Ducasse <[hidden email]> wrote:
This seems to work pretty well. With morph you may go to 800. The problem is with those cases where you have to search implementors, senders, search a string in method source, etc...I mean, those things that we do in development. Maybe for a production environment has more sense. Stef _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Free forum by Nabble | Edit this page |