[squeak-dev] The Inbox: Morphic-ct.1540.mcz

Marcel Taeumel marcel.taeumel at hpi.de
Mon Sep 23 15:12:44 UTC 2019


Hmm... this feature has quite an impact on Morph creation time and the overall memory footprint, right? Did you benchmark that somehow?

From a first impression, I would say:

-1 to keeping track of the #creatorStack because compiled methods can outdate in a long-running image
+1 to keeping track of the #officialCreator because that could help setting a breakpoint at the right place

Still ... what if we would use PasteUpMorph >> addedMorph:? How would those stacks look like? What's the user requirements here? Something in the world or more a debugging tool at the level of halos?

Maybe there could be a way to keep track of morph creation explicitely?

Morph keepTrackOfCreationDuring: someBlock.

Even with a preference, adding such a thing to Morph >> #initialize requires actual benchmarks to asses the performance and memory overhead.

Just my two cents. :-)

Best,
Marcel
Am 23.09.2019 16:47:29 schrieb Thiede, Christoph <christoph.thiede at student.hpi.uni-potsdam.de>:
How do you like that?

Can you notice a real performance impact when activating the preference? What is on Raspi?

Best,
Christoph
Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von commits at source.squeak.org <commits at source.squeak.org>
Gesendet: Montag, 23. September 2019 16:44:39
An: squeak-dev at lists.squeakfoundation.org
Betreff: [squeak-dev] The Inbox: Morphic-ct.1540.mcz
 
A new version of Morphic was added to project The Inbox:
http://source.squeak.org/inbox/Morphic-ct.1540.mcz [http://source.squeak.org/inbox/Morphic-ct.1540.mcz]

==================== Summary ====================

Name: Morphic-ct.1540
Author: ct
Time: 23 September 2019, 4:44:32.818523 pm
UUID: 064f7940-90ea-1646-a6f5-6c0a82c06e91
Ancestors: Morphic-mt.1539

Proposal: Remember & explore provenance of any morph.

Sure, this is a performance regression (that's why it's turned off by default), but when you are debugging, I could tell you of so many cases in which this can be a useful utility. Looking at #browseCreatorMethod, we can also use this to allow beginners for quickly browsing the <example> method that created a morph.

=============== Diff against Morphic-mt.1539 ===============

Item was changed:
  Object subclass: #Morph
         instanceVariableNames: 'bounds owner submorphs fullBounds color extension'
+        classVariableNames: 'HaloForAll IndicateKeyboardFocus MetaMenuForAll PreferredCornerRadius RememberProvenance UseSoftDropShadow'
-        classVariableNames: 'HaloForAll IndicateKeyboardFocus MetaMenuForAll PreferredCornerRadius UseSoftDropShadow'
         poolDictionaries: ''
         category: 'Morphic-Kernel'!
 
  !Morph commentStamp: 'klc 3/14/2017 11:30' prior: 0!
  A Morph (from the Greek "shape" or "form") is an interactive graphical object. General information on the Morphic system can be found at http://wiki.squeak.org/squeak/30 [http://wiki.squeak.org/squeak/30].
 
  Morphs exist in a tree, rooted at a World (generally a PasteUpMorph). The morphs owned by a morph are its submorphs. Morphs are drawn recursively; if a Morph has no owner it never gets drawn. To hide a Morph and its submorphs, set its #visible property to false using the #visible: method.
 
  The World (screen) coordinate system is used for most coordinates, but can be changed if there is a TransformMorph somewhere in the owner chain.
 
  My instance variables have accessor methods (e.g., #bounds, #bounds:). Most users should use the accessor methods instead of using the instance variables directly.
 
  Structure:
  instance var   Type                     Description
  bounds                         Rectangle                A Rectangle indicating my position and a size that will enclose                                                                  me.
  owner                  Morph             My parent Morph, or nil for the top-level Morph, which is a
                                 or nil                  world, typically a PasteUpMorph.
  submorphs              Array                    My child Morphs.
  fullBounds             Rectangle                A Rectangle minimally enclosing me and my submorphs.
  color                  Color                    My primary color. Subclasses can use this in different ways.
  extension              MorphExtension Allows extra properties to be stored without adding a
                                 or nil                           storage burden to all morphs.
 
  By default, Morphs do not position their submorphs. Morphs may position their submorphs directly or use a LayoutPolicy to automatically control their submorph positioning.
 
  Although Morph has some support for BorderStyle, most users should use BorderedMorph if they want borders.!

Item was added:
+ ----- Method: Morph class>>rememberProvenance (in category 'preferences') -----
+ rememberProvenance
+
+        <preference: 'Remember provenance of each morph'
+                categoryList: #(Morphic)
+                description: 'If enabled, each morph will contain a debug item to view its creator stack. This allows you to explore its provenance later. May affect performance.'
+                type: #Boolean>
+        ^ RememberProvenance ifNil: [false]!

Item was added:
+ ----- Method: Morph class>>rememberProvenance: (in category 'preferences') -----
+ rememberProvenance: aBoolean
+
+        RememberProvenance := aBoolean.!

Item was added:
+ ----- Method: Morph>>browseCreatorMethod (in category 'debug and other') -----
+ browseCreatorMethod
+
+        ^ (self valueOfProperty: #officialCreator) browse!

Item was changed:
  ----- Method: Morph>>buildDebugMenu: (in category 'debug and other') -----
  buildDebugMenu: aHand
         "Answer a debugging menu for the receiver.  The hand argument is seemingly historical and plays no role presently"
 
         | aMenu aPlayer |
         aMenu := MenuMorph new defaultTarget: self.
         aMenu addStayUpItem.
         (self hasProperty: #errorOnDraw) ifTrue:
                 [aMenu add: 'start drawing again' translated action: #resumeAfterDrawError.
                 aMenu addLine].
         (self hasProperty: #errorOnStep) ifTrue:
                 [aMenu add: 'start stepping again' translated action: #resumeAfterStepError.
                 aMenu addLine].
 
         aMenu add: 'inspect morph' translated action: #inspectInMorphic:.
         aMenu add: 'inspect owner chain' translated action: #inspectOwnerChain.
         Smalltalk isMorphic ifFalse:
                 [aMenu add: 'inspect morph (in MVC)' translated action: #inspect].
 
         self isMorphicModel ifTrue:
                 [aMenu add: 'inspect model' translated target: self model action: #inspect;
                         add: 'explore model' translated target: self model action: #explore].
         (aPlayer := self player) ifNotNil:
                 [aMenu add: 'inspect player' translated target: aPlayer action: #inspect].
 
       aMenu add: 'explore morph' translated target: self selector: #exploreInMorphic:.
 
         aMenu addLine.
         aPlayer ifNotNil:
                 [ aMenu add: 'viewer for Player' translated target: self player action: #beViewed.
         aMenu balloonTextForLastItem: 'Opens a viewer on my Player -- this is the same thing you get if you click on the cyan "View" halo handle' translated ].
 
         aMenu add: 'viewer for Morph' translated target: self action: #viewMorphDirectly.
         aMenu balloonTextForLastItem: 'Opens a Viewer on this Morph, rather than on its Player' translated.
         aMenu addLine.
 
         aPlayer ifNotNil:
                 [aPlayer class isUniClass ifTrue: [
                         aMenu add: 'browse player class' translated target: aPlayer selector: #haveFullProtocolBrowsedShowingSelector: argumentList: #(nil)]].
         aMenu add: 'browse morph class' translated target: self selector: #browseHierarchy.
+        self isMorphicModel
-        (self isMorphicModel)
                 ifTrue: [aMenu
                                 add: 'browse model class'
                                 target: self model
                                 selector: #browseHierarchy].
+        (self valueOfProperty: #officialCreator ifAbsent: [nil]) ifNotNil: [
+                aMenu add: 'browse creator method' action: #browseCreatorMethod].
+        (self hasProperty: #creatorStack) ifTrue: [
+                aMenu add: 'explore creator stack' action: #exploreCreatorStack].
         aMenu addLine.
 
         self addViewingItemsTo: aMenu.
         aMenu
                 add: 'make own subclass' translated action: #subclassMorph;
                 add: 'save morph in file' translated  action: #saveOnFile;
                 addLine;
                 add: 'call #tempCommand' translated action: #tempCommand;
                 add: 'define #tempCommand' translated action: #defineTempCommand;
                 addLine;
 
                 add: 'control-menu...' translated target: self selector: #invokeMetaMenu:;
                 add: 'edit balloon help' translated action: #editBalloonHelpText.
 
         ^ aMenu!

Item was added:
+ ----- Method: Morph>>exploreCreatorStack (in category 'debug and other') -----
+ exploreCreatorStack
+
+        ^ (self valueOfProperty: #creatorStack) explore!

Item was changed:
  ----- Method: Morph>>initialize (in category 'initialization') -----
  initialize
         "initialize the state of the receiver"
         owner := nil.
         submorphs := Array empty.
         bounds := self defaultBounds.
+        color := self defaultColor.
+        self class rememberProvenance ifTrue: [
+                | creatorStack |
+                creatorStack := thisContext home stack collect: #method.
+                self setProperty: #creatorStack toValue: creatorStack.
+                creatorStack
+                        detect: [:method | method hasPragma: #example]
+                        ifFound: [:method | self setProperty: #officialCreator toValue: method]].!
-        color := self defaultColor!


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20190923/e0463091/attachment-0001.html>


More information about the Squeak-dev mailing list