Hi folks: As part of my PhD I started to work with ImageSegment. This week I clean up all the stuff related to class discovery from there. I then wanted to put that extracted code in a separate class. I didn't like that code at all, so at the end I finished rewriting completely this stuff.
The cool thing is that: - I remove all that stuff from ImageSegment (which has nothing to do with that) - I remove that stuff from classes like Behavior and ClassDescription - I put all these as an external package that can be perfectly loaded in core - I rewrote that in style that I like much more. At least for me, it is much more easy to understand and to use now - I wrote test cases - I wrote good class comment. The repository is: http://www.squeaksource.com/ClaseUseDiscovery and the license is MIT. It is a little project, but maybe someone find it useful. This project only works with Pharo images newer than 1.1 version 11142 I paste here the class comment of CUDClassesUseDiscoverer: Cheers Mariano A CUDClassesUseDiscoverer is a little class which can be used to discovering used and unused classes during a period of time. If you want to build minimal images, it is useful also to detect for example, the amount of classes that are used just to do a simple message invokating. It helps also when some classes are being used and you don't know why. Little examples of how to use it: | aDiscoverer | aDiscoverer := CUDClassesUseDiscoverer startDiscovery. ......DO SOMETHING HERE...... aDiscoverer stopDiscovery. After that, you can: aDiscoverer activeClassesDuringDiscovery. aDiscoverer inactiveClassesDuringDiscovery. aDiscoverer activeClassesByCategoryDuringDiscovery. aDiscoverer swapOutInactiveClassesDuringDiscovery. For more details, see the tests in class CUDClassesUseDiscovererTest. Explanation: The Virtual Machine pays attention not to crash totally when you put a nil in a Method Category. In addition, there is a possibility to force a MethodDictionary fault (message induceMDFault) with the message. This method copies the methodDict in the organization slot. Actually, it creates an Array with the methodDict and the organization and set it in the organization slot. Finally, it sets a nil to the methodDict instance variable. After this is done, when that class is used and the methodDict is asked (it is very important to acces the methodDict using the accessor) it checks whether it is nil or not. If it is nil, it will search for that methodDict in the Array of the organizaction it will then copy it to the methodDict instance variable and will log in Smalltalk at: #MDFaultDict. Sometimes you will see that you have classes that were used but you do not know why or who used it. To solve this question, we can have that log. But in order to have that trace, you have to use the message startDiscoveryWithTrace instead of startDiscovery. The log will be then put in that dictionary and you can inspect it after the discovery. Taking that explanation in mind, you can follow these steps: 1) Send the message CUDClassesUseDiscoverer startDiscovery or startDiscoveryWithTrace which forces a MethodDictionary fault in all classes. Yes! It sends the message induceMDFault to all classes except classes like Array, Object, Class, Message and MethodDictionary. After this, all classes but those ones, will have the methodDict with nil. 2) Do a few things, use the system for a while. Maybe even save and resume the image. 3) Stop the discovery. This will stop everything and restore all remaining MethodDictionary faults. It will also process which classes were active and which ones were not. 4) Now, it is easy. All classes that still have a nil in the mehodDict is because they were not used, and those who have something different from nil is because they were. With the message activeClassesDuringDiscovery or inactiveClassesDuringDiscovery you can and return the active or unactive classes respectively. There is also the message swapOutInactiveClassesDuringDiscovery which makes up segments by grouping unused classes by system category and write them to disk. There are some categories that are excluded because they have problems, like System and Kernel. If you started the discovery with the message startDiscoveryWithTrace, after doing all those steps you can then inspect Smalltalk at: #MDFaultDict and you will see that in the dictionary you will have an element per class. That element is a ByteString that contains all the stack trace. This shows you all the messages and why that class was used. This approach of swapping out inactive classes have two big problems: - The granularity is too high: the class. As soon as only one method is invoked, the whole class is recovered. - It is very common to recover all classes doing a simple action. For example, searching for implementors or senders of a certain method. Because of this, when you are developing in your Smalltalk image is very likely that all classes are recovered in less than 5 minutes of work. It is not useful. Browsing or editing code seems not to be a problem, thus. Maybe this approach has more sense in production images rather than development. _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Good Work Mariano! It's always a pleasure when Smalltalker's remove complexity from core classes.
And wish you good luck with your phd work. Fernando On Jan 11, 2010, at 9:59 AM, Mariano Martinez Peck wrote: Hi folks: As part of my PhD I started to work with ImageSegment. This week I clean up all the stuff related to class discovery from there. I then wanted to put that extracted code in a separate class. I didn't like that code at all, so at the end I finished rewriting completely this stuff. _______________________________________________ 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
thanks mariano
On Jan 11, 2010, at 9:59 AM, Mariano Martinez Peck wrote: > Hi folks: As part of my PhD I started to work with ImageSegment. This week I clean up all the stuff related to class discovery from there. I then wanted to put that extracted code in a separate class. I didn't like that code at all, so at the end I finished rewriting completely this stuff. > > The cool thing is that: > > - I remove all that stuff from ImageSegment (which has nothing to do with that) > - I remove that stuff from classes like Behavior and ClassDescription > - I put all these as an external package that can be perfectly loaded in core > - I rewrote that in style that I like much more. At least for me, it is much more easy to understand and to use now > - I wrote test cases > - I wrote good class comment. > > The repository is: http://www.squeaksource.com/ClaseUseDiscovery > and the license is MIT. > > It is a little project, but maybe someone find it useful. This project only works with Pharo images newer than 1.1 version 11142 > > I paste here the class comment of CUDClassesUseDiscoverer: > > Cheers > > Mariano > > > > > > A CUDClassesUseDiscoverer is a little class which can be used to discovering used and unused classes during a period of time. If you want to build minimal images, it is useful also to detect for example, the amount of classes that are used just to do a simple message invokating. It helps also when some classes are being used and you don't know why. > > Little examples of how to use it: > > | aDiscoverer | > > aDiscoverer := CUDClassesUseDiscoverer startDiscovery. > ......DO SOMETHING HERE...... > aDiscoverer stopDiscovery. > > After that, you can: > > aDiscoverer activeClassesDuringDiscovery. > aDiscoverer inactiveClassesDuringDiscovery. > aDiscoverer activeClassesByCategoryDuringDiscovery. > aDiscoverer swapOutInactiveClassesDuringDiscovery. > > For more details, see the tests in class CUDClassesUseDiscovererTest. > > Explanation: > > The Virtual Machine pays attention not to crash totally when you put a nil in a Method Category. In addition, there is a possibility to force a MethodDictionary fault (message induceMDFault) with the message. This method copies the methodDict in the organization slot. Actually, it creates an Array with the methodDict and the organization and set it in the organization slot. Finally, it sets a nil to the methodDict instance variable. After this is done, when that class is used and the methodDict is asked (it is very important to acces the methodDict using the accessor) it checks whether it is nil or not. If it is nil, it will search for that methodDict in the Array of the organizaction it will then copy it to the methodDict instance variable and will log in Smalltalk at: #MDFaultDict. Sometimes you will see that you have classes that were used but you do not know why or who used it. To solve this question, we can have that log. But in order to have that trace, you have to use the message startDiscoveryWithTrace instead of startDiscovery. The log will be then put in that dictionary and you can inspect it after the discovery. > > Taking that explanation in mind, you can follow these steps: > > 1) Send the message CUDClassesUseDiscoverer startDiscovery or startDiscoveryWithTrace which forces a MethodDictionary fault in all classes. Yes! It sends the message induceMDFault to all classes except classes like Array, Object, Class, Message and MethodDictionary. After this, all classes but those ones, will have the methodDict with nil. > 2) Do a few things, use the system for a while. Maybe even save and resume the image. > > 3) Stop the discovery. This will stop everything and restore all remaining MethodDictionary faults. It will also process which classes were active and which ones were not. > > 4) Now, it is easy. All classes that still have a nil in the mehodDict is because they were not used, and those who have something different from nil is because they were. With the message activeClassesDuringDiscovery or inactiveClassesDuringDiscovery you can and return the active or unactive classes respectively. There is also the message swapOutInactiveClassesDuringDiscovery which makes up segments by grouping unused classes by system category and write them to disk. There are some categories that are excluded because they have problems, like System and Kernel. > > > If you started the discovery with the message startDiscoveryWithTrace, after doing all those steps you can then inspect Smalltalk at: #MDFaultDict and you will see that in the dictionary you will have an element per class. That element is a ByteString that contains all the stack trace. This shows you all the messages and why that class was used. > > This approach of swapping out inactive classes have two big problems: > > - The granularity is too high: the class. As soon as only one method is invoked, the whole class is recovered. > - It is very common to recover all classes doing a simple action. For example, searching for implementors or senders of a certain method. Because of this, when you are developing in your Smalltalk image is very likely that all classes are recovered in less than 5 minutes of work. It is not useful. Browsing or editing code seems not to be a problem, thus. Maybe this approach has more sense in production images rather than development. > > > > > > _______________________________________________ > 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 |
In reply to this post by Mariano Martinez Peck
On Jan 11, 2010, at 9:59 13AM, Mariano Martinez Peck wrote: Hi folks: As part of my PhD I started to work with ImageSegment. This week I clean up all the stuff related to class discovery from there. I then wanted to put that extracted code in a separate class. I didn't like that code at all, so at the end I finished rewriting completely this stuff. Good job, and good luck! Cheers, Henry PS. like in MessageTally, maybe a useful constructor method would be one taking a block as argument, and running trace during its execution? _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
:) I hope so ;) But it will be MUDMethodUseDiscover hahahaha
Thanks Henrik for the excellent suggestion. Committed in ClassesUseDiscover-MarianoMartinezPeck.33 Now you can do for example: aDiscoverer := CUDClassesUseDiscoverer discoverOn: [Transcript show: 'testDiscoveryOnBlocks']. aDiscoverer activeClassesDuringDiscovery Or aDiscoverer := CUDClassesUseDiscoverer discoverWithTraceOn: [Transcript show: 'testDiscoveryOnBlocks']. aDiscoverer activeClassesDuringDiscovery :) _______________________________________________ _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Free forum by Nabble | Edit this page |