[squeak-dev] The Inbox: Tools-LM.828.mcz
Eliot Miranda
eliot.miranda at gmail.com
Tue Aug 14 02:59:23 UTC 2018
Hi,
regarding
> + obj := parents at: obj ifAbsent: [nil].
> - obj := parents at: obj ifAbsent: [].
Please no. One must know that the empty block evaluates to nil. It is illiterate not to. So the verbosity is bad; it implies uncertainty (“does the empty block evaluate to nil? maybe not ‘cuz here it’s written explicitly”), it requires more typing, it’s ugly.
Another thing one should know is that
e ifTrue: [s]
is the same as
e ifTrue: [s] ifFalse: []
etc. ie, if e is false the value is nil.
_,,,^..^,,,_ (phone)
> On Aug 13, 2018, at 3:25 AM, commits at source.squeak.org wrote:
>
> A new version of Tools was added to project The Inbox:
> http://source.squeak.org/inbox/Tools-LM.828.mcz
>
> ==================== Summary ====================
>
> Name: Tools-LM.828
> Author: LM
> Time: 13 August 2018, 1:25:54.504807 pm
> UUID: 061511ca-729a-ce43-a08c-8057c24f7406
> Ancestors: Tools-tcj.827
>
> Added the ability to exclude specific objects from the PointerFinder.
> Improved the Explorer's "chase pointers" context menu to exclude the Explorer itself from the search (includes some meta-programming, not ideal, but certainly better than previously, ideas for improvement appreciated).
> Changed the way the PointerExplorer displays references, it now states the associations name on the left, and the Objects hash is moved to the right, together with the objects displayString.
> These changes make it much easier to understand how the objects are associated with each other and should make it easier to track down memory leaks.
>
> =============== Diff against Tools-tcj.827 ===============
>
> Item was changed:
> ----- Method: Inspector>>chasePointers (in category 'menu commands') -----
> chasePointers
> | selected saved |
> self selectionIndex = 0 ifTrue: [^ self changed: #flash].
> selected := self selection.
> saved := self object.
> [self object: nil.
> (Smalltalk includesKey: #PointerFinder)
> ifTrue: [PointerFinder on: selected]
> ifFalse: [self inspectPointers]]
> ensure: [self object: saved]!
>
> Item was changed:
> ----- Method: ObjectExplorer>>chasePointersForSelection (in category 'menus - actions') -----
> chasePointersForSelection
>
> + PointerFinder on: self object except: {self}, ObjectExplorerWrapper allInstances!
> - self flag: #tooMany. "mt: Note that we might want to ignore references caused by this tool."
> - self object chasePointers.!
>
> Item was changed:
> ----- Method: PointerExplorer>>rootObject: (in category 'accessing') -----
> rootObject: anObject
>
> + self root key: 'root'.
> - self root key: anObject identityHash asString.
> super rootObject: anObject.!
>
> Item was changed:
> ----- Method: PointerExplorerWrapper>>contents (in category 'accessing') -----
> contents
> "Return the wrappers with the objects holding references to item. Eldest objects come first, weak only referencers are at the end and have parentheses around their identity hash."
>
> | objects weakOnlyReferences |
> objects := self object inboundPointersExcluding: { self. self item. model }.
> weakOnlyReferences := OrderedCollection new.
> objects removeAllSuchThat: [ :each |
> each class == self class
> or: [ each class == PointerExplorer
> or: [ (each isContext
> and: [ (each objectClass: each receiver) == PointerExplorer ] )
> or: [ (each pointsOnlyWeaklyTo: self object)
> ifTrue: [ weakOnlyReferences add: each. true ]
> ifFalse: [ false ] ] ] ] ].
> ^(objects replace: [ :each |
> + self class with: each name: (self nameForParent: each) model: self object ])
> - self class with: each name: each identityHash asString model: self object ])
> addAll: (weakOnlyReferences replace: [ :each |
> + (self class with: each name: '(', (self nameForParent: each), ')' model: self object)
> - (self class with: each name: '(', each identityHash asString, ')' model: self object)
> weakOnly: true;
> yourself ]);
> yourself!
>
> Item was added:
> + ----- Method: PointerExplorerWrapper>>explorerStringFor: (in category 'converting') -----
> + explorerStringFor: anObject
> +
> + ^ anObject identityHash asString, ': ', (super explorerStringFor: anObject).!
>
> Item was added:
> + ----- Method: PointerExplorerWrapper>>memberNameFrom:to: (in category 'accessing') -----
> + memberNameFrom: aParent to: aChild
> +
> + 1 to: aParent class instSize do: [ :instVarIndex |
> + (aParent instVarAt: instVarIndex) = aChild
> + ifTrue: [ ^ '#', (aParent class instVarNameForIndex: instVarIndex)]].
> + "This also covers arrays"
> + 1 to: aParent basicSize do: [ :index |
> + (aParent basicAt: index) = aChild
> + ifTrue: [^ index asString]].
> + ^ '???'!
>
> Item was added:
> + ----- Method: PointerExplorerWrapper>>nameForParent: (in category 'accessing') -----
> + nameForParent: anObject
> +
> + ^ self memberNameFrom: anObject to: self object!
>
> Item was changed:
> Model subclass: #PointerFinder
> + instanceVariableNames: 'goal parents toDo toDoNext hasGemStone pointerList objectList parentsSize todoSize depth pointerListIndex excludedObjects'
> - instanceVariableNames: 'goal parents toDo toDoNext hasGemStone pointerList objectList parentsSize todoSize depth pointerListIndex'
> classVariableNames: ''
> poolDictionaries: ''
> category: 'Tools-Debugger'!
>
> !PointerFinder commentStamp: '<historical>' prior: 0!
> I can search for reasons why a certain object isn't garbage collected. I'm a quick port of a VisualWorks program written by Hans-Martin Mosner. Call me as shown below. I'll search for a path from a global variable to the given object, presenting it in a small morphic UI.
>
> Examples:
> PointerFinder on: self currentHand
> PointerFinder on: StandardSystemView someInstance
>
> Now, let's see why this image contains more HandMorphs as expected...
>
> HandMorph allInstancesDo: [:e | PointerFinder on: e]!
>
> Item was added:
> + ----- Method: PointerFinder class>>on:except: (in category 'instance creation') -----
> + on: anObject except: aCollection
> + ^ self new
> + goal: anObject;
> + excludedObjects: aCollection;
> + search;
> + open!
>
> Item was changed:
> ----- Method: PointerFinder>>buildList (in category 'application') -----
> buildList
> | list obj parent object key |
> list := OrderedCollection new.
> obj := goal.
>
> [list addFirst: obj.
> + obj := parents at: obj ifAbsent: [nil].
> - obj := parents at: obj ifAbsent: [].
> obj == nil] whileFalse.
> list removeFirst.
> parent := Smalltalk.
> objectList := OrderedCollection new.
> pointerList := OrderedCollection new.
> [list isEmpty]
> whileFalse:
> [object := list removeFirst.
> key := nil.
> (parent isKindOf: Dictionary)
> ifTrue: [list size >= 2
> ifTrue:
> [key := parent keyAtValue: list second ifAbsent: [].
> key == nil
> ifFalse:
> [object := list removeFirst; removeFirst.
> pointerList add: key printString , ' -> ' , object class name]]].
> key == nil
> ifTrue:
> [parent class == object ifTrue: [key := 'CLASS'].
> key == nil ifTrue: [1 to: parent class instSize do: [:i | key == nil ifTrue: [(parent instVarAt: i)
> == object ifTrue: [key := parent class instVarNameForIndex: i]]]].
> key == nil ifTrue: [parent isCompiledCode ifTrue: [key := 'literals?']].
> key == nil ifTrue: [1 to: parent basicSize do: [:i | key == nil ifTrue: [(parent basicAt: i)
> == object ifTrue: [key := i printString]]]].
> key == nil ifTrue: [(parent isMorph and: [object isKindOf: Array]) ifTrue: [key := 'submorphs?']].
> key == nil ifTrue: [key := '???'].
> pointerList add: key , ': ' , object class name, (object isMorph ifTrue: [' (', object identityHash asString, ')'] ifFalse: [ String empty ]) ].
> objectList add: object.
> parent := object]!
>
> Item was added:
> + ----- Method: PointerFinder>>excludedObjects (in category 'accessing') -----
> + excludedObjects
> +
> + ^ excludedObjects ifNil: [excludedObjects := OrderedCollection new]!
>
> Item was added:
> + ----- Method: PointerFinder>>excludedObjects: (in category 'accessing') -----
> + excludedObjects: aCollection
> +
> + excludedObjects := aCollection!
>
> Item was changed:
> ----- Method: PointerFinder>>followObject: (in category 'application') -----
> followObject: anObject
> +
> + (self excludedObjects includes: anObject)
> + ifTrue: [^ false].
> anObject outboundPointersDo: [:ea |
> (self follow: ea from: anObject)
> ifTrue: [^ true]].
> ^ false!
>
> Item was changed:
> ----- Method: PointerFinder>>initialize (in category 'application') -----
> initialize
> parents := IdentityDictionary new: 20000.
> parents at: Smalltalk put: nil.
> parents at: Processor put: nil.
> parents at: self put: nil.
>
> toDo := OrderedCollection new: 5000.
> toDo add: Smalltalk.
> + toDoNext := OrderedCollection new: 5000.!
> - toDoNext := OrderedCollection new: 5000!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20180813/ce043ea0/attachment.html>
More information about the Squeak-dev
mailing list
|